mirror of
https://github.com/unraid/webgui.git
synced 2026-04-23 18:48:49 -05:00
repo reorg
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
Menu="Tools:90"
|
||||
Type="menu"
|
||||
Title="About"
|
||||
Tag="question-circle-o"
|
||||
@@ -0,0 +1,34 @@
|
||||
Menu="Tasks:80"
|
||||
Name="Apps"
|
||||
Code="e942"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2012-2022, 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.
|
||||
*/
|
||||
?>
|
||||
<style>
|
||||
div.notice{margin:150px 0 20px 0}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function installPlugin(file) {
|
||||
openPlugin("plugin install "+file,"_(Install Plugin)_","","refresh");
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="notice">_(Click **Install** to download and install the **Community Applications** plugin)_</div>
|
||||
|
||||
<form markdown="1" name="ca_install" method="POST" target="progressFrame">
|
||||
<input type="hidden" name="file" value="https://raw.githubusercontent.com/Squidly271/community.applications/master/plugins/community.applications.plg">
|
||||
|
||||
|
||||
: <input type="button" value="_(Install)_" onclick="installPlugin(this.form.file.value)">
|
||||
</form>
|
||||
@@ -0,0 +1,81 @@
|
||||
Menu="Main:1"
|
||||
Title="Array Devices"
|
||||
Tag="database"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
function toggle_state(device,name,action) {
|
||||
var button = null;
|
||||
if (name) {
|
||||
var group = name.replace(/(\d+|\*)$/,'');
|
||||
if (name.slice(-1)!='*') {
|
||||
$('#dev-'+name).removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
|
||||
} else {
|
||||
if (group=='array') {
|
||||
$('[id^="dev-parity"]').removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
|
||||
$('[id^="dev-disk"]').removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
|
||||
} else {
|
||||
$('[id^="dev-'+group+'"]').removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
|
||||
}
|
||||
}
|
||||
} else if (device!='Clear') {
|
||||
$('[id^="dev-"]').removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
|
||||
button = '[id^=button-]';
|
||||
}
|
||||
devices.stop();
|
||||
$.post('/webGui/include/ToggleState.php',{device:device,name:name,action:action,state:'<?=$var['mdState']?>',csrf:'<?=$var['csrf_token']?>'},function(){setTimeout(function(){devices.start();},1000);if (button) $(button).prop('disabled',false);});
|
||||
}
|
||||
function display_diskio() {
|
||||
if ($.cookie('diskio')===undefined) {
|
||||
$('span.number').show(); $('span.diskio').hide();
|
||||
} else {
|
||||
$('span.diskio').show(); $('span.number').hide();
|
||||
}
|
||||
}
|
||||
function toggle_diskio(init) {
|
||||
if (!init) {
|
||||
if ($.cookie('diskio')===undefined) $.cookie('diskio','diskio',{expires:3650}); else $.removeCookie('diskio');
|
||||
}
|
||||
if ($.cookie('diskio')===undefined) {
|
||||
$('i.toggle').removeClass('fa-tachometer').addClass('fa-list');
|
||||
} else {
|
||||
$('i.toggle').removeClass('fa-list').addClass('fa-tachometer');
|
||||
}
|
||||
display_diskio();
|
||||
}
|
||||
|
||||
<?if (_var($var,'fsState')=="Started"):?>
|
||||
$('#tab1').bind({click:function() {$('i.toggle').show('slow');}});
|
||||
<?endif;?>
|
||||
</script>
|
||||
|
||||
<table class="disk_status wide">
|
||||
<thead><tr><td>_(Device)_</td><td>_(Identification)_</td><td>_(Temp)_.</td><td>_(Reads)_</td><td>_(Writes)_</td><td>_(Errors)_</td><td>_(FS)_</td><td>_(Size)_</td><td>_(Used)_</td><td>_(Free)_</td></tr></thead>
|
||||
<tbody id="array_devices">
|
||||
<?
|
||||
foreach ($disks as $disk):
|
||||
if (_var($disk,'type')=='Parity' or _var($disk,'type')=='Data')
|
||||
echo "<tr><td colspan='11'> </td></tr>";
|
||||
endforeach;
|
||||
if (_var($display,'total')) echo "<tr class='tr_last'><td colspan='11'> </td></tr>";
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
:main_array_devices_help:
|
||||
|
||||
<?if (_var($var,'fsState')=="Stopped"):?>
|
||||
<div></div>
|
||||
:main_slots_help:
|
||||
<?endif;?>
|
||||
@@ -0,0 +1,700 @@
|
||||
Menu="Main:5"
|
||||
Title="Array Operation"
|
||||
Tag="snowflake-o"
|
||||
Nchan="device_list,disk_load,parity_list"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$keyfile = file_exists(_var($var,'luksKeyfile'));
|
||||
$missing = file_exists('/var/tmp/missing.tmp');
|
||||
$encrypt = false;
|
||||
$spot = _var($var,'mdResyncPos',0)>0;
|
||||
|
||||
/* only one of $present, $missing, or $wrong will be true, or all will be false */
|
||||
$forced = $present = $wrong = false;
|
||||
foreach ($disks as $disk) {
|
||||
if (!isset($disk['fsType'])) continue;
|
||||
if (strpos(_var($disk,'fsType'),'luks:')!==false || (_var($disk,'fsType')=='auto' && (strpos(_var($var,'defaultFsType'),'luks:')!==false || _var($disk,'luksState',0)==2 || _var($disk,'luksState',0)==3))) {
|
||||
$encrypt = true;
|
||||
if (_var($disk,'luksState',0)==0) $forced = true;
|
||||
if (_var($disk,'luksState',0)==1) $present = true;
|
||||
if (_var($disk,'luksState',0)==2) $missing = true;
|
||||
if (_var($disk,'luksState',0)==3) $wrong = true;
|
||||
}
|
||||
}
|
||||
if ($forced && ($present || $missing || $wrong)) $forced = false;
|
||||
|
||||
function check_encryption() {
|
||||
global $forced, $missing, $wrong;
|
||||
if ($forced) $status = _('Enter new key');
|
||||
elseif ($missing) $status = _('Missing key');
|
||||
elseif ($wrong) $status = _('Wrong key');
|
||||
else return;
|
||||
echo "<tr><td></td><td class='gap'>",_('Encryption status').":</td><td><span class='red-text'>$status</span><span id='pass'><input name='luksReformat' type='checkbox' onchange='selectInput(this.form)'>permit reformat</span></td></tr>";
|
||||
echo "<tr><td></td><td class='gap'>",_('Encryption input').":</td><td>";
|
||||
echo "<select name='input' size='1' onchange='selectInput(this.form)'>";
|
||||
echo mk_option(1,'text',_('Passphrase'));
|
||||
echo mk_option(1,'file',_('Keyfile'));
|
||||
echo "</select></td></tr>";
|
||||
echo "<tr id='text'><td></td><td class='gap'>",_('Passphrase'),":</td><td><input type='password' name='text' maxlength='512' value='' onkeyup='selectInput(this.form)' placeholder=\""._('use printable characters only')."\"><input name='showPass' type='checkbox' onchange='selectInput(this.form)'>"._('show passphrase')."</td></tr>";
|
||||
echo "<tr id='copy'><td></td><td class='gap'>",_('Retype passphrase'),":</td><td><input type='password' name='copy' maxlength='512' value='' onkeyup='selectInput(this.form)'></td></tr>";
|
||||
echo "<tr id='file'><td></td><td class='gap'>",_('Keyfile'),":</td><td><input type='file' name='local' onchange='getFileContent(event,this.form)'></td></tr>";
|
||||
}
|
||||
function maintenance_mode() {
|
||||
echo "<tr>";
|
||||
echo "<td></td>";
|
||||
echo "<td><input type='checkbox' name='startMode' value='Maintenance'>",_('Maintenance mode'),"</td>";
|
||||
echo "<td><b>",_('Maintenance mode'),"</b> - ",_('if checked, Start array but do not mount disks'),"</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
function status_indicator() {
|
||||
global $var;
|
||||
switch (_var($var,'mdColor')) {
|
||||
case 'green-on': $orb = 'circle'; $color = 'green'; $help =_('Started, array protected'); break;
|
||||
case 'green-blink': $orb = 'circle'; $color = 'grey'; $help = _('Stopped'); break;
|
||||
case 'yellow-on': $orb = 'warning'; $color = 'yellow'; $help = _('Started, array unprotected'); break;
|
||||
case 'yellow-blink': $orb = 'warning'; $color = 'grey'; $help = _('Stopped'); break;
|
||||
}
|
||||
echo "<a class='info'><i class='fa fa-$orb orb $color-orb'></i><span>$help</span></a>";
|
||||
}
|
||||
function missing_cache() {
|
||||
global $disks;
|
||||
$missing = false;
|
||||
foreach (cache_filter($disks) as $disk) $missing |= (strpos(_var($disk,'status'),'_MISSING')!==false);
|
||||
return $missing;
|
||||
}
|
||||
function resync($d) {
|
||||
return in_array($d,['P','Q']) ? 'Parity-Sync' : 'Data-Rebuild';
|
||||
}
|
||||
function print_error($error) {
|
||||
return sprintf(_('Finding **%s** error'.($error==1?'':'s')),$error?:'0');
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
tr#copy,tr#file{display:none}
|
||||
td.gap{padding-left:26px!important}
|
||||
td.wrap{white-space:normal!important}
|
||||
span#pass{display:none;margin-left:20px}
|
||||
input[type=checkbox]{margin-left:0}
|
||||
</style>
|
||||
<script>
|
||||
var ctrl = '<span class="status <?=$tabbed?"":"vhshift"?>"><a style="cursor:pointer" class="tooltip_diskio" title="_(Toggle reads/writes display)_" onclick="toggle_diskio();return false"><i class="toggle fa"></i></a></span>';
|
||||
|
||||
function base64(str) {
|
||||
return window.btoa(unescape(encodeURIComponent(str)));
|
||||
}
|
||||
function selectInput(form) {
|
||||
<?if ($wrong && $keyfile):?>
|
||||
form.input.value = 'file';
|
||||
form.input.disabled = true;
|
||||
<?endif;?>
|
||||
if (form.input.value=='text') {
|
||||
form.file.value = '';
|
||||
form.local.value = '';
|
||||
<?if ($forced):?>
|
||||
$('#text').show();
|
||||
$('#copy').show();
|
||||
$('#pass').hide();
|
||||
$('input[name="confirmStart"]').prop('disabled',true);
|
||||
<?elseif ($missing):?>
|
||||
$('#text').show();
|
||||
$('#copy').hide();
|
||||
$('#pass').hide();
|
||||
$('input[name="confirmStart"]').prop('disabled',true);
|
||||
<?elseif ($wrong):?>
|
||||
$('#text').show();
|
||||
if ($('input[name="luksReformat"]').prop('checked')) $('#copy').show(); else $('#copy').hide();
|
||||
$('#pass').show();
|
||||
$('input[name="confirmStart"]').prop('disabled',true);
|
||||
<?endif;?>
|
||||
$('#file').hide();
|
||||
$('input[name="text"],input[name="copy"]').attr('type',$('input[name="showPass"]').prop('checked')?'text':'password');
|
||||
var item = $('input[name="confirmStart"]').length ? $('input[name="confirmStart"]') : $('#cmdStart');
|
||||
item.prop('disabled',$('#copy').is(':visible') ? (form.text.value!=form.copy.value || form.text.value=='') : form.text.value=='');
|
||||
} else {
|
||||
form.text.value = '';
|
||||
form.copy.value = '';
|
||||
$('#text').hide();
|
||||
$('#copy').hide();
|
||||
$('#file').show();
|
||||
<?if ($wrong):?>
|
||||
$('#pass').show();
|
||||
<?else:?>
|
||||
$('#pass').hide();
|
||||
<?endif;?>
|
||||
var item = $('input[name="confirmStart"]').length ? $('input[name="confirmStart"]') : $('#cmdStart');
|
||||
item.prop('disabled',!form.file.value);
|
||||
}
|
||||
}
|
||||
function getFileContent(event,form) {
|
||||
var input = event.target;
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(){form.file.value=reader.result;selectInput(form);};
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
}
|
||||
function prepareInput(form,button) {
|
||||
if (button) button.disabled = true;
|
||||
$.post('/webGui/include/Report.php',{cmd:'state',pools:'<?=implode(',',$pools)?>'},function(state) {
|
||||
if (state.length==0) {
|
||||
$(form).append('<input type="hidden" name="cmdStart" value="Start">');
|
||||
if (form.input === undefined) {
|
||||
form.submit();
|
||||
return;
|
||||
}
|
||||
form.input.disabled = true;
|
||||
form.local.disabled = true;
|
||||
form.file.disabled = true;
|
||||
form.text.disabled = true;
|
||||
form.copy.disabled = true;
|
||||
if (form.text.value) {
|
||||
var valid = new RegExp('^[ -~]+$');
|
||||
if (valid.test(form.text.value)) {
|
||||
$(form).append('<input type="hidden" name="luksKey" value="'+base64(form.text.value)+'">');
|
||||
form.submit();
|
||||
} else {
|
||||
form.input.disabled = false;
|
||||
form.local.disabled = false;
|
||||
form.file.disabled = false;
|
||||
form.text.disabled = false;
|
||||
form.copy.disabled = false;
|
||||
swal({title:"_(Printable Characters Only)_",text:"_(Use **ASCII** characters from space ' ' to tilde '~')_<br>_(Otherwise use the **keyfile** method for UTF8 input)_",html:true,type:'error',confirmButtonText:"_(Ok)_"});
|
||||
}
|
||||
return;
|
||||
}
|
||||
var data = {};
|
||||
data['#file'] = 'unused';
|
||||
data['#include'] = 'webGui/include/KeyUpload.php';
|
||||
data['file'] = form.file.value;
|
||||
$.post('/update.php',data,function(){form.submit();});
|
||||
} else {
|
||||
swal({title:"_(Wrong Pool State)_",text:state,type:'error',html:true,confirmButtonText:"_(Ok)_"});
|
||||
}
|
||||
});
|
||||
}
|
||||
function parityWarning(form) {
|
||||
if (form.md_invalidslot.checked) {
|
||||
<?if (strpos(_var($disks['parity2'],'status'),'_NP')===false):?>
|
||||
var text = "_(*Dual parity* valid requires **ALL** disks in their original slots)_";
|
||||
<?else:?>
|
||||
var text = "_(*Parity valid* requires **ALL** disks to have their original content)_";
|
||||
<?endif;?>
|
||||
} else {
|
||||
var text = "_(*Parity* disk(s) content will be overwritten)_";
|
||||
}
|
||||
swal({title:"_(Proceed to start)_",text:text,html:true,type:'warning',showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(){prepareInput(form);});
|
||||
}
|
||||
function tab0() {
|
||||
$.removeCookie('one');
|
||||
$.cookie('tab','tab0');
|
||||
}
|
||||
function stopArray(form) {
|
||||
$(form).append('<input type="hidden" name="cmdStop" value="Stop">');
|
||||
<?if ($confirm['stop']):?>
|
||||
swal({title:"_(Proceed)_?",text:"_(This will stop the array)_",type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(p){if (p) form.submit(); else $('input[name="cmdStop"]').remove();});
|
||||
<?else:?>
|
||||
form.submit();
|
||||
<?endif;?>
|
||||
}
|
||||
function stopParity(form,text) {
|
||||
$(form).append('<input type="hidden" name="cmdCheckCancel" value="">');
|
||||
<?if ($confirm['stop']):?>
|
||||
swal({title:"_(Proceed)_?",text:"_(This will stop the running operation)_: "+text,type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(p){if (p) form.submit(); else $('input[name="cmdCheckCancel"]').remove();});
|
||||
<?else:?>
|
||||
form.submit();
|
||||
<?endif;?>
|
||||
}
|
||||
function pauseParity(form) {
|
||||
$.post('/webGui/include/ParityControl.php',{action:'pause'},function(){
|
||||
$('#pauseButton').val("_(Resume)_").prop('disabled',true).prop('onclick',null).off('click').click(function(){resumeParity(form);});
|
||||
$(form).append('<input type="hidden" name="cmdCheckPause" value="">');
|
||||
form.submit();
|
||||
});
|
||||
}
|
||||
function resumeParity(form) {
|
||||
$.post('/webGui/include/ParityControl.php',{action:'resume'},function(){
|
||||
$('#pauseButton').val("_(Pause)_").prop('disabled',true).prop('onclick',null).off('click').click(function(){pauseParity(form);});
|
||||
$(form).append('<input type="hidden" name="cmdCheckResume" value="">');
|
||||
form.submit();
|
||||
});
|
||||
}
|
||||
function parityHistory() {
|
||||
openChanges("parity_history", "_(Parity Operation History)_", "phistory");
|
||||
}
|
||||
function shutdown_now(form,cmd) {
|
||||
$(form).append('<input type="hidden" name="cmd" value="'+cmd+'">');
|
||||
<?if ($confirm['down']):?>
|
||||
switch (cmd) {
|
||||
case 'reboot': var text = "_(This will reboot the system)_"; break;
|
||||
case 'shutdown': var text = "_(This will shutdown the system)_"; break;
|
||||
}
|
||||
swal({title:"_(Proceed)_?",text:text,type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(p){if (p) form.submit(); else $('input[name="cmd"]').remove();});
|
||||
<?else:?>
|
||||
form.submit();
|
||||
<?endif;?>
|
||||
}
|
||||
function toggleApply(checked) {
|
||||
$('input[name="#apply"]').prop('disabled',!checked);
|
||||
}
|
||||
<?if ($tabbed):?>
|
||||
$('.tabs').append(ctrl);
|
||||
if ($.cookie('tab')=='tab0') $('i.toggle').hide();
|
||||
$('#tab'+$('input[name$="tabs"]').length).click(function(){tab0(); $('i.toggle').hide('slow');});
|
||||
<?else:?>
|
||||
$('div[class=title]:not(":last, .disable_diskio")').each(function(){$(this).append(ctrl);});
|
||||
<?endif;?>
|
||||
$('.tooltip_diskio').tooltipster({delay:100,trigger:'custom',triggerOpen:{mouseenter:true},triggerClose:{click:false,scroll:true,mouseleave:true}});
|
||||
toggle_diskio(true);
|
||||
|
||||
<?if (_var($var,'fsState')=='Started'):?>
|
||||
var mymonitor = new NchanSubscriber('/sub/mymonitor',{subscriber:'websocket'});
|
||||
mymonitor.on('message', function(state) {
|
||||
switch (state) {
|
||||
case '0': // normal operation
|
||||
$('#stop-button').prop('disabled',false);
|
||||
$('#stop-text').html("");
|
||||
<?if (_var($var,'fsState')!="Stopped"):?>
|
||||
$('#spinup-button').prop('disabled',false);
|
||||
$('#spindown-button').prop('disabled',false);
|
||||
<?endif;?>
|
||||
<?if (_var($var,'shareUser')=='e' && $pool_devices):?>
|
||||
$('#mover-button').prop('disabled',false);
|
||||
$('#mover-text').html("<b>_(Move)_</b> _(will immediately invoke the Mover)_. <a href=\"/Main/Settings/Scheduler\"<?if($tabbed):?> onclick=\"$.cookie('one','tab2')\"<?endif;?>>(_(Schedule)_)</a>");
|
||||
<?endif;?>
|
||||
break;
|
||||
case '1': // parity running
|
||||
$('#stop-button').prop('disabled',true);
|
||||
$('#stop-text').html("<br><small>_(Disabled)_ -- _(Parity operation is running)_</small>");
|
||||
<?if (_var($var,'fsState')!="Stopped" && _var($var,'mdResync',0)>0):?>
|
||||
$('#spinup-button').prop('disabled',true);
|
||||
$('#spindown-button').prop('disabled',true);
|
||||
<?endif;?>
|
||||
<?if (_var($var,'shareUser')=='e' && $pool_devices):?>
|
||||
$('#mover-button').prop('disabled',true);
|
||||
$('#mover-text').html("_(Disabled)_ -- _(Parity operation is running)_");
|
||||
<?endif;?>
|
||||
break;
|
||||
case '2': // mover running
|
||||
$('#stop-button').prop('disabled',true);
|
||||
$('#stop-text').html("<br><small>_(Disabled)_ -- _(Mover is running)_</small>");
|
||||
<?if (_var($var,'shareUser')=='e' && $pool_devices):?>
|
||||
$('#mover-button').prop('disabled',true);
|
||||
$('#mover-text').html("_(Disabled)_ - _(Mover is running)_.");
|
||||
<?endif;?>
|
||||
break;
|
||||
case '3': // btrfs running
|
||||
$('#stop-button').prop('disabled',true);
|
||||
$('#stop-text').html("<br><small>_(Disabled)_ -- _(BTRFS operation is running)_</small>");
|
||||
<?if (_var($var,'shareUser')=='e' && $pool_devices):?>
|
||||
$('#mover-button').prop('disabled',true);
|
||||
$('#mover-text').html("_(Disabled)_ -- _(BTRFS operation is running)_");
|
||||
<?endif;?>
|
||||
break;
|
||||
}
|
||||
});
|
||||
mymonitor.start();
|
||||
<?endif;?>
|
||||
|
||||
var arraymonitor = new NchanSubscriber('/sub/arraymonitor',{subscriber:'websocket'});
|
||||
arraymonitor.on('message', function(state) {
|
||||
if (state==1 && !timers.arraymonitor) timers.arraymonitor = setTimeout(refresh,1250);
|
||||
});
|
||||
|
||||
var devices = new NchanSubscriber('/sub/devices<?=$spot?",parity":""?>',{subscriber:'websocket'});
|
||||
devices.on('message', function(msg,meta) {
|
||||
switch (<?if($spot):?>meta.id.channel()<?else:?>0<?endif;?>) {
|
||||
case 0:
|
||||
// array + pool + ua devices
|
||||
var tables = msg.split('\0');
|
||||
// get array state
|
||||
var stopped = tables.pop();
|
||||
for (var n=0; n < tables.length; n++) {
|
||||
// get table name and content
|
||||
var table = tables[n].split('\n');
|
||||
$('#'+table[0]).html(table[1]);
|
||||
}
|
||||
display_diskio();
|
||||
// stop updating when array is stopped
|
||||
if (stopped==1) {
|
||||
<?if (_var($var,'fsState')=='Started'):?>
|
||||
setTimeout(refresh,0);
|
||||
<?else:?>
|
||||
if (!timers.stopped) timers.stopped = setTimeout(function(){devices.stop(); arraymonitor.start();},1000);
|
||||
<?endif;?>
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// running parity status
|
||||
$.each(msg.split(';'),function(k,v) {if ($('#line'+k).length>0) $('#line'+k).html(v);});
|
||||
// button control
|
||||
if ($('#pauseButton').length>0 && $('#pauseButton').prop('disabled')==false) {
|
||||
if (!msg && $('#cancelButton').length>0 && $('#cancelButton').val()=="_(Cancel)_") {
|
||||
$('#cancelButton').val("_(Done)_").prop('onclick',null).off('click').click(function(){refresh();});
|
||||
$('#pauseButton').prop('disabled',true);
|
||||
$('#cancelText').html('');
|
||||
$('#line4').html("_(completed)_");
|
||||
} else {
|
||||
var form = document.arrayOps;
|
||||
if ($('#pauseButton').val()=="_(Pause)_" && msg.search("_(paused)_")!=-1) {
|
||||
$('#pauseButton').val("_(Resume)_").prop('onclick',null).off('click').click(function(){resumeParity(form);});
|
||||
} else if ($('#pauseButton').val()=="_(Resume)_" && msg.search("_(paused)_")==-1) {
|
||||
$('#pauseButton').val("_(Pause)_").prop('onclick',null).off('click').click(function(){pauseParity(form);});
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
devices.start();
|
||||
|
||||
<?if (substr(_var($var,'fsState'),-3)=='ing'):?>
|
||||
var fsState = new NchanSubscriber('/sub/fsState',{subscriber:'websocket'});
|
||||
fsState.on('message', function(msg) {
|
||||
switch (msg) {
|
||||
case 'stop':
|
||||
if (!timers.fsState) timers.fsState = setTimeout(refresh,1250);
|
||||
break;
|
||||
default:
|
||||
if (msg) $('#fsState').html(msg);
|
||||
break;
|
||||
}
|
||||
});
|
||||
fsState.start();
|
||||
<?elseif ($spot):?>
|
||||
setTimeout(function(){$('#pauseButton').prop('disabled',false);$('#cancelButton').prop('disabled',false);},250);
|
||||
<?else:?>
|
||||
var paritymonitor = new NchanSubscriber('/sub/paritymonitor',{subscriber:'websocket'});
|
||||
paritymonitor.on('message', function(busy){if (busy==1) refresh();});
|
||||
setTimeout(function(){paritymonitor.start();},5000);
|
||||
<?endif;?>
|
||||
|
||||
$(function(){
|
||||
var form = document.arrayOps;
|
||||
if (form.input !== undefined) selectInput(form);
|
||||
});
|
||||
function formatWarning(val) {
|
||||
if (val==true) {
|
||||
swal({
|
||||
title:"_(Format Unmountable disks)_",
|
||||
text: "_(Create an empty file system on the disks shown as **Unmountable** discarding all data currently on the disks and update parity to reflect this)_. "+
|
||||
"_(This is typically done when a new disk is added to the array to get it ready for files to be written to it)_.<br>"+
|
||||
"<p><br>**_(WARNING)_**"+
|
||||
"<p>_(A format is **NEVER** part of a data recovery or disk rebuild process and if done in such circumstances will normally lead to loss of all data on the disks being formatted)_.",
|
||||
type: "warning",
|
||||
html: true,
|
||||
confirmButtonText:"_(Ok)_"
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<form name="arrayOps" method="POST" action="/update.htm" target="progressFrame">
|
||||
<input type="hidden" name="startState" value="<?=htmlspecialchars(_var($var,'mdState'))?>">
|
||||
<input type="hidden" name="file" value="">
|
||||
<table markdown="1" class="array_status">
|
||||
<?switch (_var($var,'fsState')):
|
||||
case "Started":?>
|
||||
<tr><td><?status_indicator()?>**_(Started)_<?=((_var($var,'startMode')=='Maintenance')?' - _(Maintenance Mode)_':'')?>**</td>
|
||||
<td><input type="button" id="stop-button" value="_(Stop)_" onclick="stopArray(this.form)"></td>
|
||||
<td>**_(Stop)_** _(will take the array off-line)_.<span id="stop-text"></span></td></tr>
|
||||
<? if (_var($var,'fsNumUnmountable',0)>0):?>
|
||||
<tr><td>**<?=_('Unmountable disk'.(_var($var,'fsNumUnmountable',0)==1?'':'s').' present')?>:**<br>
|
||||
<? $cache = [];
|
||||
foreach ($disks as $disk) if (substr(_var($disk,'fsStatus'),0,11)=='Unmountable' || in_array(prefix(_var($disk,'name')),$cache)) {
|
||||
if (strlen(_var($disk,'id'))) echo "<span class='blue-text'>".my_disk(_var($disk,'name'))."</span> • ".my_id(_var($disk,'id'))." ("._var($disk,'device').")<br>";
|
||||
if (in_array(_var($disk,'name'),$pools)) $cache[] = $disk['name'];
|
||||
}
|
||||
?> </td><td><input type="submit" id="btnFormat" name="cmdFormat" value="_(Format)_" disabled><input type="hidden" name="unmountable_mask" value="<?=_var($var,'fsUnmountableMask')?>"></td>
|
||||
<td>**_(Format)_** _(will create a file system in all **Unmountable** disks)_.<br>
|
||||
<a class="info none img nohand"><input type="checkbox" name="confirmFormat" value="OFF" onclick="formatWarning(this.checked),$('#btnFormat').prop('disabled',!arrayOps.confirmFormat.checked)">
|
||||
<small>_(Yes, I want to do this)_</small></a>
|
||||
</td></tr>
|
||||
<? endif;
|
||||
$action = preg_split('/\s+/',_var($var,'mdResyncAction'));
|
||||
if (!$spot):
|
||||
if ($action[0]=="recon"):
|
||||
$resync = resync($action[1]);
|
||||
?> <tr><td></td><td><input type="submit" name="cmdCheckSync" value="_(Sync)_"></td><td>**<?=_('Sync')?>** <?=_("will start **$resync**")?>.</td></tr>
|
||||
<? elseif ($action[0]=="clear"):?>
|
||||
<tr><td></td><td><input type="submit" name="cmdCheckClear" value="_(Clear)_"></td><td>**_(Clear)_** _(will start **Disk-Clear** of new data disk(s))_.</td></tr>
|
||||
<? else:
|
||||
if ($action[0]=="check" && count($action)>1):?>
|
||||
<tr><td>_(Parity is valid)_.</td><td><input type="submit" name="cmdCheck" value="_(Check)_"></td><td>**_(Check)_** _(will start **Parity-Check**)_. <a href="/Main/Settings/Scheduler"<?if ($tabbed):?> onclick="$.cookie('one','tab1')"<?endif;?>>(_(Schedule)_)</a>
|
||||
<br><input type="checkbox" name="optionCorrect" value="correct" checked><small>_(Write corrections to parity)_</small></td></tr>
|
||||
<? elseif ($action[0]=="check"):?>
|
||||
<tr><td></td><td><input type="submit" name="cmdCheck" value="_(Check)_"></td><td>**_(Check)_** _(will start **Read-Check** of all array disks)_.</td></tr>
|
||||
<? endif;?>
|
||||
<tr><td></td><td><input type="button" value="_(History)_" onclick="parityHistory()"></td>
|
||||
<? [$date,$duration,$speed,$status,$error,$action,$size] = last_parity_log();
|
||||
if (_var($var,'sbSyncExit',0)!=0):?>
|
||||
<td class="wrap"><?=sprintf(_('Last check incomplete on **%s**'),_(my_time(_var($var,'sbSynced2',0)).day_count(_var($var,'sbSynced2',0)),0))?><?if (_var($var,'sbSynced2')):?>
|
||||
<br><i class="fa fa-fw fa-dot-circle-o"></i> _(Error code)_: <?=my_error(_var($var,'sbSyncExit'))?>
|
||||
<br><i class="fa fa-fw fa-search"></i> <?=print_error(_var($var,'sbSyncErrs',0))?><?endif;?></td></tr>
|
||||
<? elseif (_var($var,'sbSynced',0)==0):
|
||||
if ($status==0):?>
|
||||
<td class="wrap"><?=sprintf(_('Last checked on **%s**'),_(my_time($date).day_count($date),0))?>
|
||||
<br><i class="fa fa-fw fa-clock-o"></i> _(Duration)_: <?=my_check($duration,$speed)?>
|
||||
<br><i class="fa fa-fw fa-search"></i> <?=print_error($error)?></td></tr>
|
||||
<? else:?>
|
||||
<td class="wrap"><?=sprintf(_('Last check incomplete on **%s**'),_(my_time($date).day_count($date),0))?>
|
||||
<br><i class="fa fa-fw fa-dot-circle-o"></i> _(Error code)_: <?=my_error($status)?>
|
||||
<br><i class="fa fa-fw fa-search"></i> <?=print_error($error)?></td></tr>
|
||||
<? endif;
|
||||
elseif (_var($var,'sbSynced2',0)==0):
|
||||
if ($status==0):?>
|
||||
<td class="wrap"><?=sprintf(_('Last checked on **%s**'),_(my_time(_var($var,'sbSynced',0)).day_count(_var($var,'sbSynced',0)),0))?>
|
||||
<br><i class="fa fa-fw fa-clock-o"></i> _(Duration)_: <?=my_check($duration,$speed)?>
|
||||
<br><i class="fa fa-fw fa-search"></i> <?=print_error($error)?></td></tr>
|
||||
<? else:?>
|
||||
<td class="wrap"><?=sprintf(_('Last check incomplete on **%s**'),_(my_time(_var($var,'sbSynced',0)).day_count(_var($var,'sbSynced',0)),0))?>
|
||||
<br><i class="fa fa-fw fa-dot-circle-o"></i> _(Error code)_: <?=my_error($status)?>
|
||||
<br><i class="fa fa-fw fa-search"></i> <?=print_error($error)?></td></tr>
|
||||
<? endif;
|
||||
else:?>
|
||||
<td class="wrap"><?=sprintf(_('Last check completed on **%s**'),_(my_time(_var($var,'sbSynced2',0)).day_count(_var($var,'sbSynced2',0)),0))?>
|
||||
<br><i class="fa fa-fw fa-clock-o"></i> _(Duration)_: <?=my_check($duration,$speed)?>
|
||||
<br><i class="fa fa-fw fa-search"></i> <?=print_error(_var($var,'sbSyncErrs',0))?></td></tr>
|
||||
<? endif;
|
||||
endif;
|
||||
else:
|
||||
if ($action[0]=="recon"):
|
||||
$resync = resync($action[1]);
|
||||
?> <tr><td><?=_("$resync in progress")?>.</td><td>
|
||||
<input type="button" id="pauseButton"<?if (_var($var,'mdResync')):?> value="_(Pause)_" onclick="pauseParity(this.form)"<?else:?> value="_(Resume)_" onclick="resumeParity(this.form)"<?endif;?> disabled>
|
||||
<input type="button" id="cancelButton" value="_(Cancel)_" onclick="stopParity(this.form,'<?=$resync?>')" disabled></td>
|
||||
<td id="cancelText"><?if (_var($var,'mdResync')):?>**<?=_('Pause')?>** <?=_("will pause $resync")?>.<?else:?>**<?=_('Resume')?>** <?=_("will resume $resync")?>.<?endif;?><br>**<?=_('Cancel')?>** <?=_("will stop $resync")?>.
|
||||
<br>_(WARNING: canceling may leave the array unprotected)_!</td></tr>
|
||||
<? elseif ($action[0]=="clear"):?>
|
||||
<tr><td>_(Disk-Clear in progress)_.</td><td>
|
||||
<input type="button" id="pauseButton"<?if (_var($var,'mdResync')):?> value="_(Pause)_" onclick="pauseParity(this.form)"<?else:?> value="_(Resume)_" onclick="resumeParity(this.form)"<?endif;?> disabled>
|
||||
<input type="button" id="cancelButton" value="_(Cancel)_" onclick="stopParity(this.form,'Disk-Clear')" disabled></td>
|
||||
<td id="cancelText"><?if (_var($var,'mdResync')):?>**_(Pause)_** _(will pause Disk-Clear)_.<?else:?>**_(Resume)_** _(will resume Disk-Clear)_.<?endif;?><br>**_(Cancel)_** _(will stop Disk-Clear)_.</td></tr>
|
||||
<? elseif ($action[0]=="check" && count($action)>1):?>
|
||||
<tr><td>_(Parity-Check in progress)_.</td><td>
|
||||
<input type="button" id="pauseButton"<?if (_var($var,'mdResync')):?> value="_(Pause)_" onclick="pauseParity(this.form)"<?else:?> value="_(Resume)_" onclick="resumeParity(this.form)"<?endif;?> disabled>
|
||||
<input type="button" id="cancelButton" value="_(Cancel)_" onclick="stopParity(this.form,'Parity-Check')" disabled></td>
|
||||
<td id="cancelText"><?if (_var($var,'mdResync')):?>**_(Pause)_** _(will pause Parity-Check)_.<?else:?>**_(Resume)_** _(will resume Parity-Check)_.<?endif;?><br>**_(Cancel)_** _(will stop Parity-Check)_.</td></tr>
|
||||
<? elseif ($action[0]=="check"):?>
|
||||
<tr><td>_(Read-Check in progress)_.</td><td>
|
||||
<input type="button" id="pauseButton"<?if (_var($var,'mdResync')):?> value="_(Pause)_" onclick="pauseParity(this.form)"<?else:?> value="_(Resume)_" onclick="resumeParity(this.form)"<?endif;?> disabled>
|
||||
<input type="button" id="cancelButton" value="_(Cancel)_" onclick="stopParity(this.form,'Read-Check')" disabled></td>
|
||||
<td id="cancelText"><?if (_var($var,'mdResync')):?>**_(Pause)_** _(will pause Read-Check)_.<?else:?>**_(Resume)_** _(will resume Read-Check)_.<?endif;?><br>**_(Cancel)_** _(will stop Read-Check)_.</td></tr>
|
||||
<? endif;
|
||||
$stamps = '/var/tmp/stamps.ini';
|
||||
$synced = file_exists($stamps) ? explode(',',file_get_contents($stamps)) : [];
|
||||
$sbSynced = array_shift($synced) ?: _var($var,'sbSynced');
|
||||
$sbUpdate = _var($var,'mdResyncDt') ? $sbSynced : _var($var,'sbUpdated');?>
|
||||
<tr><td></td><td><input type="button" value="_(History)_" onclick="parityHistory()"></td>
|
||||
<td><?=sprintf(_('Current operation %s on **%s**'),(_var($var,'mdResyncDt')?_('started'):_('paused')),_(my_time($sbUpdate).day_count($sbUpdate),0))?></td></tr>
|
||||
<tr><td>_(Total size)_:</td><td id="line0"></td><td></td></tr>
|
||||
<tr><td>_(Elapsed time)_:</td><td id="line1"></td><td></td></tr>
|
||||
<tr><td>_(Current position)_:</td><td id="line2"></td><td></td></tr>
|
||||
<tr><td>_(Estimated speed)_:</td><td id="line3"></td><td></td></tr>
|
||||
<tr><td>_(Estimated finish)_:</td><td id="line4"></td><td></td></tr>
|
||||
<? if ($action[0]=="check"):?>
|
||||
<? if (count($action)>1):?>
|
||||
<tr><td><?=_var($var,'mdResyncCorr')==0 ? _('Sync errors detected') : _('Sync errors corrected')?>:</td><td id="line5"></td><td></td></tr>
|
||||
<? else:?>
|
||||
<tr><td><?=_var($var,'mdResyncCorr')==0 ? _('Read errors detected') : _('Read errors corrected')?>:</td><td id="line5"></td><td></td></tr>
|
||||
<? endif;
|
||||
endif;
|
||||
endif;
|
||||
break;
|
||||
case "Starting":?>
|
||||
<tr><td><?status_indicator()?>**_(Starting)_...**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td><td></td></tr>
|
||||
<tr><td></td><td><input type="button" value="_(History)_" onclick="parityHistory()"></td><td></td></tr>
|
||||
<? break;
|
||||
case "Formatting":?>
|
||||
<tr><td><?status_indicator()?>**_(Started, formatting)_...**</td><td><input type="submit" name="cmdStop" value="_(Stop)_" disabled></td><td></td></tr>
|
||||
<tr><td></td><td><input type="button" value="_(History)_" onclick="parityHistory()"></td><td></td></tr>
|
||||
<? break;
|
||||
case "Copying":?>
|
||||
<tr><td><?status_indicator()?>**_(Starting, copying)_... <span id="fsState"></span>**</td><td><input type="submit" name="cmdNoCopy" value="_(Cancel)_"></td><td></td></tr>
|
||||
<tr><td></td><td><input type="button" value="_(History)_" onclick="parityHistory()"></td>
|
||||
<td><?=sprintf(_('Current operation %s on **%s**'),_('started'),_(my_time(_var($var,'sbUpdated',0)).day_count(_var($var,'sbSynced',0)),0))?></td></tr>
|
||||
<? break;
|
||||
case "Clearing":?>
|
||||
<tr><td><?status_indicator()?>**_(Started, clearing)_... <span id="fsState"></span>**</td><td><input type="submit" name="cmdNoClear" value="_(Cancel)_"></td><td></td></tr>
|
||||
<tr><td></td><td><input type="button" value="_(History)_" onclick="parityHistory()"></td>
|
||||
<td><?=sprintf(_('Current operation %s on **%s**'),_('started'),_(my_time(_var($var,'sbUpdated',0)).day_count(_var($var,'sbSynced',0)),0))?></td></tr>
|
||||
<? break;
|
||||
case "Stopping":?>
|
||||
<tr><td><?status_indicator()?>**_(Stopping)_...**</td><td><input type="submit" name="cmdStop" value="_(Stop)_" disabled></td><td></td></tr>
|
||||
<? break;
|
||||
case "Stopped":
|
||||
if (_var($var,'configValid')=="error"):?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
|
||||
<td>_(Invalid, missing or expired)_ <a href="/Tools/Registration">_(registration key)_</a>.</td></tr>
|
||||
<? elseif (_var($var,'configValid')=="invalid"):?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
|
||||
<td>_(Too many attached devices. Please consider upgrading your)_ <a href="/Tools/Registration">_(registration key)_</a>.</td></tr>
|
||||
<? elseif (_var($var,'configValid')=="nokeyserver"):?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
|
||||
<td>_(Cannot contact key-server. Please check your)_ <a href="/Settings/NetworkSettings">_(network settings)_</a>.</td></tr>
|
||||
<? elseif (_var($var,'configValid')=="withdrawn"):?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
|
||||
<td>_(This Unraid OS release has been withdrawn and may no longer be used. Please)_ <a href="/Plugins">_(update)_</a> _(your server)_.</td></tr>
|
||||
<? else:
|
||||
switch (_var($var,'mdState')):
|
||||
case "STARTED":
|
||||
?> <tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
|
||||
<td>**_(Start)_** _(will bring the array on-line)_.</td></tr>
|
||||
<? maintenance_mode();
|
||||
check_encryption();
|
||||
break;
|
||||
case "STOPPED":
|
||||
$action = explode(' ',_var($var,'mdResyncAction'));
|
||||
if ($action[0]=="recon"):
|
||||
$resync = resync($action[1]);
|
||||
?> <tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
|
||||
<td>**<?=_('Start')?>** <?=_("will bring the array on-line and start **$resync**")?>.</td></tr>
|
||||
<? elseif ($action[0]=="clear"):?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(New data disk(s) detected)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
|
||||
<td>**_(Start)_** _(will bring the array on-line and start **Disk-Clear** of new data disk(s))_.</td></tr>
|
||||
<? elseif (_var($var,'sbClean')!="yes" && $action[0]=="check" && count($action)>1):?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Unclean shutdown detected)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
|
||||
<td>**_(Start)_** _(will bring the array on-line and start **Parity-Check**)_.
|
||||
<br><input type="checkbox" name="optionCorrect" value="correct" checked><small>_(Write corrections to parity)_</small></td></tr>
|
||||
<? elseif (_var($var,'sbClean')!="yes" && $action[0]=="check"):?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Unclean shutdown detected)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
|
||||
<td>**_(Start)_** _(will bring the array on-line)_.</td></tr>
|
||||
<? elseif (missing_cache()):?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Missing Cache disk)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)" disabled></td>
|
||||
<td>**_(Start)_** _(will remove the missing cache disk and then bring the array on-line)_.
|
||||
<br><input type="checkbox" name="confirmStart" value="OFF" onclick="$('#cmdStart').prop('disabled',!arrayOps.confirmStart.checked)"><small>_(Yes, I want to do this)_</small></td></tr>
|
||||
<? else:?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
|
||||
<td>**_(Start)_** _(will bring the array on-line)_.</td></tr>
|
||||
<? endif;
|
||||
maintenance_mode();
|
||||
check_encryption();
|
||||
break;
|
||||
case "NEW_ARRAY":
|
||||
if (strpos(_var($disks['parity'],'status'),"DISK_NP")===0 && strpos(_var($disks['parity2'],'status'),"DISK_NP")===0):?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
|
||||
<td>**_(Start)_** _(will record all disk information and bring the array on-line)_.
|
||||
<br>_(The array will be immediately available, but **unprotected** since *parity* has not been assigned)_.</td></tr>
|
||||
<? else:?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="parityWarning(this.form,this)"></td>
|
||||
<td>**_(Start)_** _(will record all disk information, bring the array on-line, and start Parity-Sync)_.
|
||||
<br>_(The array will be immediately available, but **unprotected** until Parity-Sync completes)_.
|
||||
<br><input type="checkbox" name="md_invalidslot" value="99">_(Parity is already valid)_.</td></tr>
|
||||
<? endif;
|
||||
maintenance_mode();
|
||||
check_encryption();
|
||||
break;
|
||||
case "DISABLE_DISK":?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Missing disk)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)" disabled></td>
|
||||
<td>**_(Start)_** _(will disable the missing disk and then bring the array on-line. Install a replacement disk as soon as possible)_.
|
||||
<br><input type="checkbox" name="confirmStart" value="OFF" onclick="$('#cmdStart').prop('disabled',!arrayOps.confirmStart.checked)"><small>_(Yes, I want to do this)_</small></td></tr>
|
||||
<? maintenance_mode();
|
||||
check_encryption();
|
||||
break;
|
||||
case "RECON_DISK":?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Replacement disk installed)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
|
||||
<td>**_(Start)_** _(will start **Parity-Sync** and/or **Data-Rebuild**)_.</td></tr>
|
||||
<? maintenance_mode();
|
||||
check_encryption();
|
||||
break;
|
||||
case "SWAP_DSBL":
|
||||
if (_var($var,'fsCopyPrcnt')=="100"):?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Upgrading disk/swapping parity)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form,this)"></td>
|
||||
<td>**_(Start)_** _(will expand the file system of the data disk (if possible); then bring the array on-line and start Data-Rebuild)_.</td></tr>
|
||||
<? maintenance_mode();
|
||||
check_encryption();
|
||||
else:?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Upgrading disk/swapping parity)_.</td><td><input type="submit" name="cmdCopy" value="_(Copy)_" disabled></td>
|
||||
<td>**_(Copy)_** _(will copy the parity information to the new *parity* disk)_.
|
||||
<br>_(Once copy completes, the array may be Started, to initiate Data-Rebuild of the disabled disk)_.
|
||||
<br><input type="checkbox" name="confirmStart" value="OFF" onclick="arrayOps.cmdCopy.disabled=!arrayOps.confirmStart.checked"><small>_(Yes, I want to do this)_</small></td></tr>
|
||||
<? endif;
|
||||
break;
|
||||
case "ERROR:INVALID_EXPANSION":?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Invalid expansion)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
|
||||
<td>_(You may not add new disk(s) and also remove existing disk(s))_.</td></tr>
|
||||
<? break;
|
||||
case "ERROR:NEW_DISK_TOO_SMALL":?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Replacement disk is too small)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
|
||||
<td>_(The replacement disk must be as big or bigger than the original)_.</td></tr>
|
||||
<? break;
|
||||
case "ERROR:PARITY_NOT_BIGGEST":?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Disk in parity slot is not biggest)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
|
||||
<td>_(If this is a new array, move the largest disk into the *parity* slot)_.
|
||||
<br>_(If you are adding a new disk or replacing a disabled disk, try Parity-Swap)_.</td></tr>
|
||||
<? break;
|
||||
case "ERROR:TOO_MANY_MISSING_DISKS":?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Invalid configuration)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
|
||||
<td>_(Too many wrong and/or missing disks)_!</td></tr>
|
||||
<? break;
|
||||
case "ERROR:NO_DATA_DISKS":?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_**. _(No data disks)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
|
||||
<td>_(No array data disks have been assigned)_!</td></tr>
|
||||
<? break;
|
||||
endswitch;
|
||||
endif;
|
||||
endswitch;?>
|
||||
<tr><td></td><td class="line" colspan="2"></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<?if (_var($var,'fsState')!="Stopped"):?>
|
||||
<?if ($keyfile):?>
|
||||
<form name="delete_keyfile" method="POST" action="/update.php" target="progressFrame">
|
||||
<input type="hidden" name="#file" value="unused">
|
||||
<input type="hidden" name="#include" value="webGui/include/KeyUpload.php">
|
||||
<table markdown="1" class="array_status noshift">
|
||||
<tr><td></td><td><input type="submit" name="#apply" value="_(Delete)_" disabled></td><td>**_(Delete)_** _(will delete the encryption keyfile)_.
|
||||
<br><input type="checkbox" onchange="toggleApply(this.checked)"><small>_(Yes, I want to do this)_</small></td></tr>
|
||||
<tr><td></td><td class="line" colspan="2"></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<?endif;?><!-- markdown fix -->
|
||||
<table markdown="1" class="array_status noshift">
|
||||
<tr><td></td><td><input type="button" id="spinup-button" onclick="$('[id^=button-]').prop('disabled',true);toggle_state('up')" value="_(Spin Up)_"><input type="button" id="spindown-button" onclick="$('[id^=button-]').prop('disabled',true);toggle_state('down')" value="_(Spin Down)_"></td>
|
||||
<td>**_(Spin Up)_** _(will immediately spin up all disks)_.<br>**_(Spin Down)_** _(will immediately spin down all disks)_.</td></tr>
|
||||
<tr><td></td><td><input type="button" value="_(Clear Stats)_" onclick="toggle_state('Clear')"></td><td>**_(Clear Stats)_** _(will immediately clear all disk statistics)_.</td></tr>
|
||||
<tr><td></td><td class="line" colspan="2"></td></tr>
|
||||
</table>
|
||||
<?if (_var($var,'shareUser')=='e' && $pool_devices):?>
|
||||
<form name="mover_schedule" method="POST" action="/update.htm" target="progressFrame">
|
||||
<table markdown="1" class="array_status noshift">
|
||||
<tr><td></td><td><input type="submit" id="mover-button" name="cmdStartMover" value="_(Move)_"></td><td id="mover-text"></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<?endif;?>
|
||||
<?elseif ($wrong && $keyfile):?>
|
||||
<form name="delete_keyfile" method="POST" action="/update.php" target="progressFrame">
|
||||
<input type="hidden" name="#file" value="unused">
|
||||
<input type="hidden" name="#include" value="webGui/include/KeyUpload.php">
|
||||
<table markdown="1" class="array_status noshift">
|
||||
<tr><td></td><td><input type="submit" name="#apply" value="_(Delete)_"></td><td>**_(Delete)_** _(will delete the encryption keyfile)_.</td></tr>
|
||||
<tr><td></td><td class="line" colspan="2"></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<?endif;?><!-- markdown fix -->
|
||||
<form name="shutdownOps" method="POST" action="/webGui/include/Boot.php">
|
||||
<table markdown="1" class="array_status noshift">
|
||||
<tr><td></td><td><input type="button" name="reboot" value="_(Reboot)_" onclick="shutdown_now(this.form,'reboot')"><input type="button" name="shutdown" value="_(Shutdown)_" onclick="shutdown_now(this.form,'shutdown')"></td>
|
||||
<td>**_(Reboot)_** _(will activate a *clean* system reset)_.<br>**_(Shutdown)_** _(will activate a *clean* system power down)_.<br><input type="checkbox" name="safemode"><small>_(Reboot in safe mode)_</small></td></tr>
|
||||
<tr><td></td><td class="line" colspan="2"></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<!-- markdown fix --></p><?if (isset($display['sleep'])) eval('?>'.parse_file($display['sleep']))?>
|
||||
|
||||
:array_status_help:
|
||||
<?if (_var($var,'fsState')=="Stopped"):?>
|
||||
:array_devices_help:
|
||||
|
||||
<?if ($encrypt):?>
|
||||
<div></div>
|
||||
:encryption_help:
|
||||
<?endif;?>
|
||||
<?endif;?>
|
||||
@@ -0,0 +1,30 @@
|
||||
Menu="Main:3"
|
||||
Title="Boot Device"
|
||||
Tag="paw"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
<?if (_var($var,'fsState')=="Started"):?>
|
||||
$('#tab3').bind({click:function() {$('i.toggle').show('slow');}});
|
||||
<?endif;?>
|
||||
</script>
|
||||
|
||||
<table class="disk_status wide">
|
||||
<thead><tr><td>_(Device)_</td><td>_(Identification)_</td><td>_(Temp)_.</td><td>_(Reads)_</td><td>_(Writes)_</td><td>_(Errors)_</td><td>_(FS)_</td><td>_(Size)_</td><td>_(Used)_</td><td>_(Free)_</td></tr></thead>
|
||||
<tbody id="boot_device">
|
||||
<?if (isset($disks['flash'])) echo "<tr><td colspan='11'> </td></tr>";?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
:boot_device_help:
|
||||
@@ -0,0 +1,61 @@
|
||||
Title="_(Index of)_ $dir"
|
||||
Tag="navicon"
|
||||
Markdown="false"
|
||||
---
|
||||
<?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 cap($dir,$p) {
|
||||
return mb_substr($dir,$p,1)=='/' ? '/' : '';
|
||||
}
|
||||
function truepath($dir) {
|
||||
$dir = preg_replace('://+:','/',htmlspecialchars_decode($dir));
|
||||
$bits = array_filter(explode('/',$dir),'mb_strlen');
|
||||
$path = [];
|
||||
foreach ($bits as $bit) {
|
||||
if ($bit=='.') continue;
|
||||
if ($bit=='..') array_pop($path); else $path[] = $bit;
|
||||
}
|
||||
return cap($dir,0).implode('/',$path);
|
||||
}
|
||||
$dir = htmlspecialchars(str_replace('\\','\\\\',truepath($dir)));
|
||||
?>
|
||||
<style>
|
||||
.loc{text-align:left!important;padding-left:0!important}
|
||||
.title span.left{text-transform:none}
|
||||
</style>
|
||||
<script>
|
||||
$(function(){
|
||||
timers.browse = setTimeout(function(){$('div.spinner.fixed').show('slow');},500);
|
||||
$.get('/webGui/include/Browse.php',{dir:encodeURIComponent("<?=$dir?>"),path:"<?=$path?>"},function(data){
|
||||
clearTimeout(timers.browse);
|
||||
var table = $('table.indexer');
|
||||
var thead = table.find('thead');
|
||||
var col = $.cookie('col')||1;
|
||||
var dir = $.cookie('dir')||0;
|
||||
table.find('tbody,tfoot').remove();
|
||||
thead.after(data);
|
||||
table.bind('sortEnd',function(e,t){
|
||||
var sort = e.target.config.sortList.toString().split(',');
|
||||
$.cookie('col',sort[0]);
|
||||
$.cookie('dir',sort[1]);
|
||||
});
|
||||
$('div.spinner.fixed').hide('slow');
|
||||
table.tablesorter({sortList:[[col,dir],[1,0]],sortAppend:[[1,0]],textAttribute:'data'});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<table class="indexer tablesorter shift">
|
||||
<thead><tr><th>_(Type)_</th><th class='sorter-text'>_(Name)_</th><th>_(Size)_</th><th>_(Last Modified)_</th><th style="width:200px">_(Location)_</th></tr></thead>
|
||||
</table>
|
||||
<input type="button" value="_(Done)_" onclick="done('Browse')">
|
||||
@@ -0,0 +1,30 @@
|
||||
Menu="CPUset:3"
|
||||
Title="CPU Isolation"
|
||||
Tag="icon-cpu"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
<form name="is">
|
||||
<input type="hidden" name="names" value="isolcpus">
|
||||
<table class='tablesorter shift' style='width:auto'>
|
||||
<thead><tr><th><i class="fa fa-list"></i> _(Isolation)_</th><?create()?></tr></thead>
|
||||
<tbody id="table-is"><?=$spinner?></tbody>
|
||||
</table>
|
||||
<input type="button" value="_(Apply)_" onclick="apply(this.form)" disabled><input type="button" value="_(Done)_" onclick="done()"><span id="wait-is" class="red-text" style="display:none"><i class="fa fa-spinner fa-spin"></i> _(Please wait)_...</span>
|
||||
</form>
|
||||
<?if (!$safemode):?>
|
||||
<?else:?>
|
||||
<div class="notice">_(CPU isolation is prohibited while system is running in SAFE MODE)_!</div>
|
||||
<?endif;?>
|
||||
|
||||
:cpu_isolation_help:
|
||||
@@ -0,0 +1,30 @@
|
||||
Menu="CPUset:2"
|
||||
Title="CPU Pinning Docker"
|
||||
Tag="icon-cpu"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
<?if ($dockerd):?>
|
||||
<form name="ct">
|
||||
<input type="hidden" name="names" id="names-ct" value="">
|
||||
<table class='tablesorter shift' style='width:auto'>
|
||||
<thead><tr><th><i class="fa fa-list"></i> _(Container)_</th><?create()?></tr></thead>
|
||||
<tbody id="table-ct"><?=$spinner?></tbody>
|
||||
</table>
|
||||
<input type="button" value="_(Apply)_" onclick="apply(this.form)" disabled><input type="button" value="_(Done)_" onclick="done()"><span id="wait-ct" class="red-text" style="display:none"><i class="fa fa-spinner fa-spin"></i> _(Please wait)_...</span>
|
||||
</form>
|
||||
<?else:?>
|
||||
<div class="notice">_(No CPU pinning available. Docker service must be started)_</div>
|
||||
<?endif;?>
|
||||
|
||||
:cpu_pinning_help:
|
||||
@@ -0,0 +1,4 @@
|
||||
Menu="OtherSettings"
|
||||
Title="CPU Pinning"
|
||||
Type="xmenu"
|
||||
Icon="icon-cpu-pinning"
|
||||
@@ -0,0 +1,209 @@
|
||||
Menu="CPUset:1"
|
||||
Title="CPU Pinning VM"
|
||||
Tag="icon-cpu"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
* Copyright 2012-2021, 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$libvirtd = pgrep('libvirtd')!==false;
|
||||
$dockerd = pgrep('dockerd')!==false;
|
||||
|
||||
$cpus = cpu_list();
|
||||
$total = count($cpus);
|
||||
$spinner = "<tr><td colspan='".($total+2)."'><div class='spinner'></div></td></tr>";
|
||||
$cpuset = implode(';',$cpus);
|
||||
|
||||
function create() {
|
||||
// create the table header. Make multiple rows when CPU cores are many ;)
|
||||
global $total,$cpus;
|
||||
$loop = floor(($total-1)/32)+1;
|
||||
$text = [];
|
||||
for ($c = 0; $c < $loop; $c++) {
|
||||
$max = ($c==$loop-1 ? ($total%32?:32) : 32);
|
||||
for ($n = 0; $n < $max; $n++) {
|
||||
[$cpu1, $cpu2] = my_preg_split('/[,-]/',$cpus[$c*32+$n]);
|
||||
if (empty($text[$n])) $text[$n] = '';
|
||||
$text[$n] .= "$cpu1<br>";
|
||||
if ($cpu2) $text[$n] .= "$cpu2<br>";
|
||||
}
|
||||
}
|
||||
$label = implode('<br>',array_fill(0,$loop,'CPU:'.($cpu2 ? '<br>HT:':'')));
|
||||
echo "<th>$label</th>".implode(array_map(function($t){return "<th>$t</th>";},$text));
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
table.tablesorter tr>th+th{text-align:right;vertical-align:top}
|
||||
table.tablesorter tr>td+td+td{vertical-align:top}
|
||||
table.tablesorter tr>th+th+th,table.tablesorter tr>td+td{text-align:center}
|
||||
table.tablesorter th:first-child,table.tablesorter td:first-child{width:180px;text-align:left}
|
||||
input.flat{margin:0}
|
||||
input.lock{margin:0}
|
||||
</style>
|
||||
<script>
|
||||
String.prototype.strip = function(){return this.replace(/ |\(|\)|\[|\]/g,'');}
|
||||
String.prototype.encode = function(){return this.replace(/\./g,'%2e');}
|
||||
|
||||
function apply(form) {
|
||||
// disable buttons
|
||||
$(form).find('input[value="_(Apply)_"]').prop('disabled',true);
|
||||
$(form).find('input[value="_(Reset)_"]').val("_(Done)_").prop('onclick',null).off('click').click(function(){done();});
|
||||
$('input[value="_(Done)_"]').prop('disabled',true);
|
||||
var wait = 0;
|
||||
var id = $(form).prop('name');
|
||||
var args = {};
|
||||
args['id'] = id;
|
||||
args['names'] = form.names.value.encode();
|
||||
// get the 'checked' cpus
|
||||
$(form).find('input[type=checkbox]').each(function(){
|
||||
if ($(this).prop('checked')) args[$(this).prop('name').encode()] = 'on';
|
||||
});
|
||||
// show the instant wait message
|
||||
$('#wait-'+id).show();
|
||||
// step 1: prepare the update and report back the changes
|
||||
$.post('/webGui/include/UpdateOne.php',args,function(reply){
|
||||
if (reply.error) {
|
||||
swal({type:'error',title:"_(Assignment error)_",text:reply.error,html:true,confirmButtonText:"_(Ok)_"},function(){
|
||||
$('#wait-'+id).hide();
|
||||
$(form).find('input[value="_(Done)_"]').val("_(Reset)_").prop('disabled',false).prop('onclick',null).off('click').click(function(){reset($('form[name="'+id+'"]'));});
|
||||
});
|
||||
} else if (reply.success) {
|
||||
var data = reply.success.split(';');
|
||||
wait = data.length;
|
||||
for (var i=0; i < data.length; i++) {
|
||||
var name = data[i];
|
||||
$('#'+id+'-'+name.strip()).show('slow');
|
||||
// step 2: apply the changes by updating the vm or container
|
||||
$.post('/webGui/include/UpdateTwo.php',{id:id,name:encodeURIComponent(name)},function(reply){
|
||||
if (reply.error) {
|
||||
// report error and reload table
|
||||
swal({type:'error',title:"_(Execution error)_",text:reply.error,html:true,confirmButtonText:"_(Ok)_"},function(){
|
||||
$('#wait-'+id).hide();
|
||||
$('input[value="_(Done)_"]').prop('disabled',false);
|
||||
reset($('form[name="'+id+'"]'));
|
||||
});
|
||||
} else {
|
||||
$('#'+id+'-'+reply.success.strip()).hide('slow');
|
||||
// cleanup when all is done
|
||||
if (!--wait) {
|
||||
setTimeout(function(){$('#wait-'+id).hide();},500);
|
||||
$('input[value="_(Done)_"]').prop('disabled',false);
|
||||
// isolated cpus, need reboot notice?
|
||||
if (id == 'is') notice();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
$('#wait-'+id).hide();
|
||||
$('input[value="_(Done)_"]').prop('disabled',false);
|
||||
if (id == 'is') notice();
|
||||
}
|
||||
});
|
||||
}
|
||||
function vm() {
|
||||
// fetch the current vm assignments
|
||||
$.post('/webGui/include/CPUset.php',{id:'vm',cpus:'<?=$cpuset?>'},function(d){
|
||||
var data = d.split('\0');
|
||||
$('#table-vm').html(data[0]);
|
||||
$('#names-vm').val(data[1]);
|
||||
buttons(document.vm);
|
||||
});
|
||||
}
|
||||
function thread2containers(n) {
|
||||
const selector = $('form[name=ct]').find(`[name$=":${n}"]`);
|
||||
const checkboxes = selector.length;
|
||||
const checked = selector.filter(':checked').length;
|
||||
selector.prop('checked', (checkboxes - checked > checked ? true : false)).change();
|
||||
}
|
||||
function ct() {
|
||||
// fetch the current container assignments
|
||||
$.post('/webGui/include/CPUset.php',{id:'ct',cpus:'<?=$cpuset?>'},function(d){
|
||||
var data = d.split('\0');
|
||||
$('#table-ct').html(data[0]);
|
||||
$('#names-ct').val(data[1]);
|
||||
buttons(document.ct);
|
||||
// inject thread to containers toggles
|
||||
if($('a[onclick^="thread2containers"]').length === 0) {
|
||||
$('form[name=ct]').find('thead tr th:gt(1)').each((i, elem) => {
|
||||
elem.innerHTML = elem.innerHTML.replace(/(\d+)/g, '<a href="#" onclick="thread2containers(this.innerText);return false;" title="_(Toggle thread to containers)_">$1</a>');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function is() {
|
||||
// fetch the current isolcpu assignments
|
||||
$.post('/webGui/include/CPUset.php',{id:'is',cpus:'<?=$cpuset?>'},function(d){
|
||||
$('#table-is').html(d);
|
||||
buttons(document.is);
|
||||
<?if ($safemode):?>
|
||||
$('#table-is').find('input[type=checkbox]').prop('disabled',true);
|
||||
<?endif;?>
|
||||
});
|
||||
}
|
||||
function notice() {
|
||||
// notice to reboot system after changes
|
||||
var message = "_(CPU Isolation: A reboot is required to apply changes)_";
|
||||
|
||||
$.post('/webGui/include/CPUset.php',{id:'cmd'},function(d){
|
||||
if (d==1) addRebootNotice(message); else removeRebootNotice(message);
|
||||
});
|
||||
}
|
||||
function reset(form) {
|
||||
// undo changes without a complete refresh of the page
|
||||
$(form).find('input[value="_(Apply)_"]').prop('disabled',true);
|
||||
$(form).find('input[value="_(Reset)_"]').val("_(Done)_").prop('onclick',null).off('click').click(function(){done();});
|
||||
switch ($(form).prop('name')) {
|
||||
case 'vm': $('#table-vm').html("<?=$spinner?>"); $('div.spinner').html(unraid_logo); vm(); break;
|
||||
case 'ct': $('#table-ct').html("<?=$spinner?>"); $('div.spinner').html(unraid_logo); ct(); break;
|
||||
case 'is': $('#table-is').html("<?=$spinner?>"); $('div.spinner').html(unraid_logo); is(); break;
|
||||
}
|
||||
}
|
||||
function buttons(form) {
|
||||
$(form).find('input[type=checkbox]').each(function(){$(this).on('change',function(){
|
||||
var total = $(form).find('input[type=checkbox]').length;
|
||||
var checked = 'input[name^="'+$(this).prop('name').split(':')[0]+':'+'"]:checked';
|
||||
var cores = $(form).find(checked).length;
|
||||
// vms must have at least one core selected
|
||||
if ($(form).prop('name')=='vm') $(form).find(checked).prop('disabled',cores<2);
|
||||
// isolation may not have all cores selected
|
||||
if ($(form).prop('name')=='is' && $(this).prop('checked')) $(this).prop('checked',cores<total);
|
||||
// we need the Apply and Done buttons react on checkbox changes
|
||||
$(form).find('input[value="_(Apply)_"]').prop('disabled',false);
|
||||
$(form).find('input[value="_(Done)_"]').val("_(Reset)_").prop('onclick',null).off('click').click(function(){reset(form);});
|
||||
});});
|
||||
}
|
||||
$(function(){
|
||||
<?if ($libvirtd):?>
|
||||
vm();
|
||||
<?endif;?>
|
||||
<?if ($dockerd):?>
|
||||
ct();
|
||||
<?endif;?>
|
||||
is();
|
||||
notice();
|
||||
});
|
||||
</script>
|
||||
<?if ($libvirtd):?>
|
||||
<form name="vm">
|
||||
<input type="hidden" name="names" id="names-vm" value="">
|
||||
<table class='tablesorter shift' style='width:auto'>
|
||||
<thead><tr><th><i class="fa fa-list"></i> _(VM)_</th><?create()?></tr></thead>
|
||||
<tbody id="table-vm"><?=$spinner?></tbody>
|
||||
</table>
|
||||
<input type="button" value="_(Apply)_" onclick="apply(this.form)" disabled><input type="button" value="_(Done)_" onclick="done()"><span id="wait-vm" class="red-text" style="display:none"><i class="fa fa-spinner fa-spin"></i> _(Please wait)_...</span>
|
||||
</form>
|
||||
<?else:?>
|
||||
<div class="notice">_(No CPU pinning available. VM service must be started)_</div>
|
||||
<?endif;?>
|
||||
|
||||
:cpu_vms_help:
|
||||
@@ -0,0 +1,128 @@
|
||||
Menu="Main:2"
|
||||
Title="Pool Devices"
|
||||
Tag="bullseye"
|
||||
Cond="($pool_devices || $var['fsState']=='Stopped')"
|
||||
---
|
||||
<?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 makeList($list) {
|
||||
return implode(',',array_map('escapestring',$list));
|
||||
}
|
||||
function sharename($share) {
|
||||
return basename($share,'.cfg');
|
||||
}
|
||||
$bgcolor = strstr('white,azure',$display['theme']) ? '#f2f2f2' : '#1c1c1c';
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/jquery.ui.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/plugins/dynamix.docker.manager/styles/style-{$display['theme']}.css")?>">
|
||||
<style>
|
||||
table.divider{margin-top:20px}
|
||||
</style>
|
||||
<script>
|
||||
function validate(poolname) {
|
||||
var valid = /^[a-z]([a-z0-9_-]*[a-z_-])*$/;
|
||||
var reserved = [<?=makeList(explode(',',_var($var,'reservedNames')))?>];
|
||||
var shares = [<?=makeList(array_map('sharename',glob('boot/config/shares/*.cfg',GLOB_NOSORT)))?>];
|
||||
var pools = [<?=makeList($pools)?>];
|
||||
if (!poolname.trim()) return false;
|
||||
if (reserved.includes(poolname)) {
|
||||
swal({title:"_(Invalid pool name)_",text:"_(Do not use reserved names)_",html:true,type:'error',confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
} else if (shares.includes(poolname)) {
|
||||
swal({title:"_(Invalid pool name)_",text:"_(Do not use user share names)_",html:true,type:'error',confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
} else if (pools.includes(poolname)) {
|
||||
swal({title:"_(Invalid pool name)_",text:"_(Pool name already exists)_",html:true,type:'error',confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
} else if (!valid.test(poolname)) {
|
||||
swal({title:"_(Invalid pool name)_",text:"_(Use only lowercase with no special characters or leading/trailing digits)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function addPoolPopup() {
|
||||
var popup = $('#dialogAddPool');
|
||||
// Load popup with the template info
|
||||
popup.html($("#templatePopupPool").html());
|
||||
// Start Dialog section
|
||||
popup.dialog({
|
||||
title: "_(Add Pool)_",
|
||||
resizable: false,
|
||||
width: 600,
|
||||
modal: true,
|
||||
show : {effect:'fade', duration:250},
|
||||
hide : {effect:'fade', duration:250},
|
||||
buttons: {
|
||||
"_(Add)_": function() {
|
||||
if (validate($(this).find('input[name="poolName"]').val())) {
|
||||
$(this).find('form').submit();
|
||||
$(this).dialog('close');
|
||||
}
|
||||
},
|
||||
"_(Cancel)_": function() {
|
||||
$(this).dialog('close');
|
||||
}
|
||||
}
|
||||
});
|
||||
$(".ui-dialog .ui-dialog-titlebar").addClass('menu');
|
||||
$('.ui-dialog .ui-dialog-titlebar-close').css({'display':'none'});
|
||||
$(".ui-dialog .ui-dialog-title").css({'text-align':'center','width':'100%'});
|
||||
$(".ui-dialog .ui-dialog-content").css({'padding-top':'15px','vertical-align':'bottom'});
|
||||
$(".ui-widget-content").css({'background':'<?=$bgcolor?>'});
|
||||
$(".ui-button-text").css({'padding':'0px 5px'});
|
||||
}
|
||||
|
||||
<?if (_var($var,'fsState')=="Started"):?>
|
||||
$('#tab2').bind({click:function() {$('i.toggle').show('slow');}});
|
||||
<?endif;?>
|
||||
</script>
|
||||
|
||||
<?$i = 0?>
|
||||
<?foreach ($pools as $pool):?>
|
||||
<?if (isset($disks[$pool]['devices']) or _var($var,'fsState')=="Stopped"):?>
|
||||
<table class="disk_status wide<?=$i?' divider':''?>">
|
||||
<thead><tr><td>_(Device)_</td><td>_(Identification)_</td><td>_(Temp)_.</td><td>_(Reads)_</td><td>_(Writes)_</td><td>_(Errors)_</td><td>_(FS)_</td><td>_(Size)_</td><td>_(Used)_</td><td>_(Free)_</td></tr></thead>
|
||||
<tbody id="pool_device<?=$i++?>">
|
||||
<?foreach (cache_filter($disks) as $disk) if (prefix($disk['name'])==$pool) echo "<tr><td colspan='11'> </td></tr>"?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?endif;?>
|
||||
<?endforeach;?>
|
||||
<?if (_var($var,'fsState')=="Stopped"):?>
|
||||
<input type="button" value="_(Add Pool)_" style="margin:0" onclick="addPoolPopup()">
|
||||
|
||||
<div id="dialogAddPool" style="display:none"></div>
|
||||
<div id="templatePopupPool" style="display:none">
|
||||
<form markdown="1" method="POST" action="/update.htm" target="progressFrame" onsubmit="return validate(this.poolName.value)">
|
||||
<input type="hidden" name="changeSlots" value="apply">
|
||||
_(Name)_:
|
||||
: <input type="text" name="poolName" maxlength="40" value="<?=count($pools)==0?'cache':''?>">
|
||||
|
||||
_(Slots)_:
|
||||
: <select name="poolSlots">
|
||||
<?for ($n=1; $n<=_var($var,'MAX_CACHESZ',0); $n++):?>
|
||||
<?=mk_option(1,$n,$n)?>
|
||||
<?endfor;?>
|
||||
</select>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<?endif;?>
|
||||
|
||||
:cache_devices_help:
|
||||
|
||||
<?if (_var($var,'fsState')=="Stopped"):?>
|
||||
<div></div>
|
||||
:cache_slots_help:
|
||||
<?endif;?>
|
||||
@@ -0,0 +1,48 @@
|
||||
Menu="UserPreferences"
|
||||
Title="Confirmations"
|
||||
Icon="icon-confirmations"
|
||||
Tag="check-square"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
|
||||
<form markdown="1" name="confirm_settings" method="POST" action="/update.php" target="progressFrame">
|
||||
<input type="hidden" name="#file" value="dynamix/dynamix.cfg"/>
|
||||
<input type="hidden" name="#section" value="confirm"/>
|
||||
_(Confirm reboot & powerdown commands)_:
|
||||
: <select name="down">
|
||||
<?=mk_option($confirm['down'], "0", _('No'))?>
|
||||
<?=mk_option($confirm['down'], "1", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:confirm_reboot_help:
|
||||
|
||||
_(Confirm array stop command)_:
|
||||
: <select name="stop">
|
||||
<?=mk_option($confirm['stop'], "0", _('No'))?>
|
||||
<?=mk_option($confirm['stop'], "1", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:confirm_array_stop_help:
|
||||
|
||||
<?if (isset($confirm['sleep'])):?>
|
||||
_(Confirm sleep command)_:
|
||||
: <select name="sleep">
|
||||
<?=mk_option($confirm['sleep'], "0", _('No'))?>
|
||||
<?=mk_option($confirm['sleep'], "1", _('Yes'))?>
|
||||
</select>
|
||||
<?endif;?>
|
||||
|
||||
|
||||
: <input type="submit" name="#apply" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
@@ -0,0 +1,50 @@
|
||||
Menu="About"
|
||||
Title="Credits"
|
||||
Icon="icon-credits"
|
||||
Tag="trophy"
|
||||
---
|
||||
**Unraid webGUI** Copyright © 2005-2023, [Lime Technology, Inc.](http://lime-technology.com)
|
||||
|
||||
**Dynamix** Copyright © 2012-2023, Bergware International.
|
||||
|
||||
**Extended Docker Configuration Page** Copyright © 2014-2021, Guilherme Jardim.
|
||||
|
||||
**VM Manager** Copyright © 2015-2021, Eric Schultz, Derek Macias.
|
||||
|
||||
**APC UPS Configuration Page** Copyright © 2015, Dan Landon.
|
||||
|
||||
**Simple Features** Copyright © 2012, Andrew Hamer-Adams.
|
||||
|
||||
**SysDev UI** Copyright © 2020, Justin Nolan
|
||||
|
||||
**Community Applications** Copyright © 2015-2023, Andrew Zawadzki
|
||||
|
||||
The Software comprising the Unraid webGui, which is all files within this repository **except** for
|
||||
files listed below, is licensed under GPL version 2.
|
||||
|
||||
* The Lime Technology and Unraid logos are property of Lime Technology, Inc.
|
||||
and may not be used in any other project without written permission from Lime Technology, Inc.
|
||||
|
||||
* Settings, Tools and Case icons. Copyright © 2018-2020, [Magnus Engø.](http://www.magnusengo.net/) Used with permission.
|
||||
|
||||
**Unraid**® is a registered trademark of [Lime Technology, Inc.](http://lime-technology.com)
|
||||
|
||||
This file shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
<?
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
|
||||
$plugins = '/var/log/plugins';
|
||||
$credits = [];
|
||||
|
||||
foreach (glob("$plugins/lang-*.xml", GLOB_NOSORT) as $link) {
|
||||
$xml_file = @readlink($link);
|
||||
if ($xml_file === false) continue;
|
||||
$lang = language('Language', $xml_file);
|
||||
$local = language('LanguageLocal', $xml_file);
|
||||
$author = language('Author', $xml_file);
|
||||
$credits[] = "<li><p><i>$lang ($local)</i> translation by $author</p></li>";
|
||||
}
|
||||
if (count($credits)) echo '<br><b>Language Translations</b> Copyright © 2020-2023, <a href="http://lime-technology.com">Lime Technology, Inc.</a><br><ul>'.implode('',$credits).'</ul>';
|
||||
?>
|
||||
<br><input type="button" value="_(Done)_" onclick="done()">
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
Menu="Tasks:1"
|
||||
Type="xmenu"
|
||||
Tabs="false"
|
||||
Code="e943"
|
||||
Lock="true"
|
||||
Load="30"
|
||||
@@ -0,0 +1,63 @@
|
||||
Menu="Dashboard:0"
|
||||
Cond="version_compare(parse_ini_file('/etc/unraid-version')['version'],'6.11.9','>')"
|
||||
---
|
||||
<?PHP
|
||||
/*
|
||||
Create a .page file based on this example file and store the file in your plugin directory
|
||||
Make sure this file has a unique name not used by the GUI or other plugins
|
||||
|
||||
This is an example configuration which is used to add custom tiles to the dashboard
|
||||
Placement of one or more custom tiles is done under column1, column2 or column3
|
||||
A column can have as many new custom tiles as needed, each custom tile is a <tbody> element
|
||||
Each tile must have these two properties set:
|
||||
|
||||
"_(description)_" - this is the (translated) description shown in the Content Manager window
|
||||
"_(Tile tile)_" - this is the (translated) title of the tile shown in bold on the screen
|
||||
|
||||
The content of the tile can be any text as required by your plugin, this content is placed inside the <td> element
|
||||
A number of predefined spans are available to make fields of certain widths and maybe used to follow the GUI alignment
|
||||
These are:
|
||||
<span class="w18">
|
||||
<span class="w26">
|
||||
<span class="w36">
|
||||
<span class="w44">
|
||||
<span class="w72">
|
||||
*/
|
||||
$pluginname = "myplugin"; // substitute this entry with the name of your plugin
|
||||
|
||||
$mytiles[$pluginname]['column1'] =
|
||||
<<<EOT
|
||||
<tbody title="_(description)_">
|
||||
<tr><td>_(Tile title)_</td></tr>
|
||||
<tr><td>
|
||||
## content of the tile ##<br>
|
||||
single field
|
||||
</td></tr>
|
||||
</tbody>
|
||||
EOT;
|
||||
|
||||
$mytiles[$pluginname]['column2'] =
|
||||
<<<EOT
|
||||
<tbody title="_(description)_">
|
||||
<tr><td>_(Tile title)_</td></tr>
|
||||
<tr><td>
|
||||
## content of the tile ##<br>
|
||||
<span class="w26" style="background-color:orange">field 1</span>
|
||||
<span class="w72" style="background-color:lightgreen">field 2</span>
|
||||
</td></tr>
|
||||
</tbody>
|
||||
EOT;
|
||||
|
||||
$mytiles[$pluginname]['column3'] =
|
||||
<<<EOT
|
||||
<tbody title="_(description)_">
|
||||
<tr><td>_(Tile title)_</td></tr>
|
||||
<tr><td>
|
||||
## content of the tile ##<br>
|
||||
<span class="w26" style="background-color:orange">field 1</span>
|
||||
<span class="w36" style="background-color:lightgreen">field 2</span>
|
||||
<span class="w36" style="background-color:lightblue">field 3<span>
|
||||
</td></tr>
|
||||
</tbody>
|
||||
EOT;
|
||||
?>
|
||||
@@ -0,0 +1,89 @@
|
||||
Menu="OtherSettings"
|
||||
Title="Date and Time"
|
||||
Icon="icon-clock"
|
||||
Tag="clock-o"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
* Copyright 2012-2021, 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.
|
||||
*/
|
||||
?>
|
||||
<?$keys = explode("\n", file_get_contents('webGui/include/timezones.key'));?>
|
||||
|
||||
<form markdown="1" name="datetime_settings" method="POST" action="/update.htm" target="progressFrame">
|
||||
_(Current date and time)_:
|
||||
: <?=_(my_time(time()),0)?>
|
||||
|
||||
_(Time zone)_:
|
||||
: <select name="timeZone" size="1"><?
|
||||
foreach ($keys as $key) {
|
||||
[$timezone, $city] = my_explode('|', $key);
|
||||
echo mk_option($var['timeZone'], $timezone, $city);
|
||||
}
|
||||
?></select>
|
||||
|
||||
:timezone_help:
|
||||
|
||||
_(Use NTP)_:
|
||||
: <select name="USE_NTP" size="1" onchange="checkDateTimeSettings(this.form)">
|
||||
<?=mk_option($var['USE_NTP'], "yes", _('Yes'))?>
|
||||
<?=mk_option($var['USE_NTP'], "no", _('No'))?>
|
||||
</select>
|
||||
|
||||
:use_ntp_help:
|
||||
|
||||
_(NTP server)_ 1:
|
||||
: <input type="text" name="NTP_SERVER1" maxlength="40" class="narrow" value="<?=htmlspecialchars($var['NTP_SERVER1'])?>">
|
||||
|
||||
:ntp_server1_help:
|
||||
|
||||
_(NTP server)_ 2:
|
||||
: <input type="text" name="NTP_SERVER2" maxlength="40" class="narrow" value="<?=htmlspecialchars($var['NTP_SERVER2'])?>">
|
||||
|
||||
:ntp_server2_help:
|
||||
|
||||
_(NTP server)_ 3:
|
||||
: <input type="text" name="NTP_SERVER3" maxlength="40" class="narrow" value="<?=htmlspecialchars($var['NTP_SERVER3'])?>">
|
||||
|
||||
:ntp_server3_help:
|
||||
|
||||
_(NTP server)_ 4:
|
||||
: <input type="text" name="NTP_SERVER4" maxlength="40" class="narrow" value="<?=htmlspecialchars($var['NTP_SERVER4'])?>">
|
||||
|
||||
:ntp_server4_help:
|
||||
|
||||
_(New date and time)_:
|
||||
: <input type="text" name="newDateTime" maxlength="20" class="narrow" value="<?=my_time(time(), "%F %T")?>">
|
||||
|
||||
:current_time_help:
|
||||
|
||||
|
||||
: <input type="submit" name="setDateTime" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
|
||||
<script>
|
||||
function checkDateTimeSettings() {
|
||||
form = document.datetime_settings;
|
||||
if (form.USE_NTP.value=="yes") {
|
||||
form.newDateTime.disabled=true;
|
||||
form.NTP_SERVER1.disabled=false;
|
||||
form.NTP_SERVER2.disabled=false;
|
||||
form.NTP_SERVER3.disabled=false;
|
||||
form.NTP_SERVER4.disabled=false;
|
||||
} else {
|
||||
form.newDateTime.disabled=false;
|
||||
form.NTP_SERVER1.disabled=true;
|
||||
form.NTP_SERVER2.disabled=true;
|
||||
form.NTP_SERVER3.disabled=true;
|
||||
form.NTP_SERVER4.disabled=true;
|
||||
}
|
||||
}
|
||||
$(checkDateTimeSettings);
|
||||
</script>
|
||||
@@ -0,0 +1,2 @@
|
||||
Type="xmenu"
|
||||
Tabs="true"
|
||||
@@ -0,0 +1,32 @@
|
||||
Menu="Device New"
|
||||
Title="Attributes"
|
||||
Tag="address-card-o"
|
||||
Cond="strpos(_var($disks[$name],'status'),'_NP')===false"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
$(function() {
|
||||
$.post("/webGui/include/SmartInfo.php",{cmd:'attributes',port:'<?=$dev?>',name:'<?=$name?>'}, function(data) {
|
||||
$('#disk_attributes').html(data);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<table class='share_status small'>
|
||||
<thead><td style="width:40px">#</td><td>_(Attribute Name)_</td><td>_(Flag)_</td><td>_(Value)_</td><td>_(Worst)_</td><td>_(Threshold)_</td><td>_(Type)_</td><td>_(Updated)_</td><td>_(Failed)_</td><td style="width:145px">_(Raw Value)_</td></thead>
|
||||
<tbody id="disk_attributes"><tr><td colspan='10'><div class="spinner"></div></td></tr></tbody>
|
||||
</table>
|
||||
<input type="button" value="_(Done)_" onclick="done()">
|
||||
|
||||
:smart_attributes_help:
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
Menu="Device New"
|
||||
Title="Capabilities"
|
||||
Tag="building"
|
||||
Cond="strpos(_var($disks[$name],'status'),'_NP')===false"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
$(function() {
|
||||
$.post("/webGui/include/SmartInfo.php",{cmd:'capabilities',port:'<?=$dev?>',name:'<?=$name?>'}, function(data) {
|
||||
$('#disk_capabilities_div').html(data);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<div id="disk_capabilities_div" class='share_status small'>
|
||||
|
||||
</div>
|
||||
<input type="button" value="_(Done)_" onclick="done()">
|
||||
|
||||
:smart_capabilities_help:
|
||||
@@ -0,0 +1,39 @@
|
||||
Menu="Device New"
|
||||
Title="Identity"
|
||||
Tag="user"
|
||||
Cond="strpos(_var($disks[$name],'status'),'_NP')===false"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<style>
|
||||
input[type=date]{border:none;margin-left:-2px;padding-left:0;background:transparent;box-shadow:none}
|
||||
select.noframe{border:none;margin-left:0;padding-left:0;background:transparent;box-shadow:none}
|
||||
</style>
|
||||
<script>
|
||||
function disklog(disk,key,value) {
|
||||
$.post('/webGui/include/DiskLog.php',{disk:disk,key:key,value:value});
|
||||
}
|
||||
$(function() {
|
||||
$.post("/webGui/include/SmartInfo.php",{cmd:'identify',port:'<?=$dev?>',name:'<?=$name?>'}, function(data) {
|
||||
$('#disk_identify').html(data);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<table class='share_status small'>
|
||||
<thead><td style="width:33%">_(Title)_</td><td>_(Information)_</td></thead>
|
||||
<tbody id="disk_identify"><tr><td colspan='2'><div class="spinner"></div></td></tr></tbody>
|
||||
</table>
|
||||
<input type="button" value="_(Done)_" onclick="done()">
|
||||
|
||||
:smart_identity_help:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,123 @@
|
||||
Menu="UNRAID-OS"
|
||||
Title="Diagnostics"
|
||||
Icon="icon-diagnostics"
|
||||
Tag="tv"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2012-2022, 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$zip = htmlspecialchars(str_replace(' ','_',strtolower($var['NAME'])));
|
||||
?>
|
||||
<style>
|
||||
ul,li{margin:0;padding-top:0;padding-bottom:0}
|
||||
pre.pre{margin:30px 0}
|
||||
pre>p{margin:0;padding:0}
|
||||
pre#swaltext{height:600px!important}
|
||||
@media (max-width:960px){pre#swaltext{height:400px!important}}
|
||||
@media (max-width:960px){.sweet-alert.nchan{height:600px;width:900px;margin-left:-470px}}
|
||||
@media (max-height:768px){pre#swaltext{height:400px!important}}
|
||||
@media (max-height:768px){.sweet-alert.nchan{height:600px;width:900px;margin-left:-470px}}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
var diagnosticsFile = "";
|
||||
var nchan_diagnostics = new NchanSubscriber('/sub/diagnostics',{subscriber:'websocket'});
|
||||
|
||||
nchan_diagnostics.on('message', function(data) {
|
||||
if (data == '_DONE_') {
|
||||
nchan_diagnostics.stop();
|
||||
$('.sweet-alert').hide('fast').removeClass('nchan');
|
||||
swal.close();
|
||||
location = diagnosticsFile;
|
||||
setTimeout(cleanUp,4000);
|
||||
} else if (data) {
|
||||
let box = $('pre#swaltext');
|
||||
box.html(box.html()+'<br>'+data).scrollTop(box[0].scrollHeight);
|
||||
}
|
||||
});
|
||||
|
||||
function cleanUp() {
|
||||
if (document.hasFocus()) {
|
||||
$.post('/webGui/include/Download.php',{cmd:'delete',file:diagnosticsFile});
|
||||
$("#download").attr("disabled",false);
|
||||
diagnosticsFile = "";
|
||||
} else {
|
||||
setTimeout(cleanUp,2000);
|
||||
}
|
||||
}
|
||||
|
||||
function zipfile(){
|
||||
var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
|
||||
var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0,-1);
|
||||
return '<?=$zip?>-diagnostics-'+localISOTime.substr(0,16).replace(/[-:]/g,'').replace('T','-')+'.zip';
|
||||
}
|
||||
|
||||
function diagnostics(file) {
|
||||
var anonymize = $('#anonymize').is(':checked') ? '' : '-a';
|
||||
nchan_diagnostics.start();
|
||||
$.post('/webGui/include/Download.php',{cmd:'diag',file:file,anonymize:anonymize},function(zip) {
|
||||
if (zip) {
|
||||
diagnosticsFile = zip;
|
||||
swal({title:"_(Downloading)_...",text:"/boot/logs"+zip+"<hr><pre id='swaltext'></pre>",html:true,animation:'none',showConfirmButton:false});
|
||||
$('.sweet-alert').addClass('nchan');
|
||||
$('button.confirm').prop('disabled',true);
|
||||
} else {
|
||||
nchan_diagnostics.stop();
|
||||
$("#download").attr("disabled",false);
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
:diagnostics_1_plug:
|
||||
This utility is used for troubleshooting purposes. It will collect all of the system information and configuration files, and package these files in a single ZIP file which can be saved locally.
|
||||
Subsequently, this file can be included in your correspondence with Limetech or the Unraid forum.
|
||||
|
||||
This will help others to quickly get the inside information of your system and provide better support to your problem. The following information
|
||||
and configuration files are collected:
|
||||
:end
|
||||
|
||||
<pre class="pre" markdown="1">
|
||||
:diagnostics_2_plug:
|
||||
+ */config*
|
||||
<br>copy all *\*.cfg files*, *go* file and the *super.dat* file. These are configuration files.
|
||||
+ */config/shares*
|
||||
<br>copy all *\*.cfg* files. These are user share settings files.
|
||||
+ *Syslog file(s)*
|
||||
<br>copy the current *syslog* file and any previous existing *syslog* files.
|
||||
+ *System*
|
||||
<br>save output of the following commands:
|
||||
<br>lsscsi, lspci, lsusb, free, lsof, ps, ethtool & ifconfig.
|
||||
<br>display of iommu groups.
|
||||
<br>display of command line parameters (e.g. pcie acs override, pci stubbing, etc).
|
||||
<br>save system variables.
|
||||
+ *SMART reports*
|
||||
<br>save a SMART report of each individual disk present in your system.
|
||||
+ *Docker*
|
||||
<br>save files *docker.log*, *libvirtd.log*, *libvirt/qemu/\*.log* and *vfio-pci*.
|
||||
:end
|
||||
</pre>
|
||||
|
||||
:diagnostics_3_plug:
|
||||
Clicking **Download** will start the collection process and then instruct your browser to save the zip file locally.
|
||||
|
||||
*No personal information such as user names, passwords, or any other file contents not specified above is included
|
||||
by Unraid OS; however, your server name, IP address, and user share names* **will** *be included.*
|
||||
|
||||
*Note that 3rd-party plugins **may** or may not store personal information in plugin-specific configuration files and/or output
|
||||
to the system log.*
|
||||
|
||||
*Use* **Anonymize diagnostics** *when publishing the diagnostics file in the public forum. In private communication with Limetech it is recommended to uncheck this setting and capture all information unaltered.*
|
||||
:end
|
||||
|
||||
<input id='download' type="button" value="_(Download)_" onclick="$(this).attr('disabled',true);diagnostics(zipfile())"><input type="button" value="_(Done)_" onclick="done()"><input type="checkbox" id="anonymize" checked>_(Anonymize diagnostics)_
|
||||
@@ -0,0 +1,70 @@
|
||||
Type="xmenu"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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 clone_list($disk) {
|
||||
global $pools;
|
||||
return strpos($disk['status'],'_NP')===false && ($disk['type']=='Data' || in_array($disk['name'],$pools));
|
||||
}
|
||||
if (count($pages)==2) $tabbed = false;
|
||||
$refs = []; $n = 0;
|
||||
|
||||
foreach ($disks as $ref) {
|
||||
if ($ref['type']!='Data' && !in_array($ref['name'],$pools)) continue;
|
||||
if ($ref['fsColor']=='grey-off') continue;
|
||||
$refs[] = $ref['name'];
|
||||
if ($ref['name']==$name) $i = $n;
|
||||
$n++;
|
||||
}
|
||||
$end = count($refs)-1;
|
||||
$prev = urlencode($i>0 ? $refs[$i-1] : $refs[$end]);
|
||||
$next = urlencode($i<$end ? $refs[$i+1] : $refs[0]);
|
||||
?>
|
||||
<style>
|
||||
div.clone1{position:absolute;right:0;margin-top:0}
|
||||
div.clone2{position:absolute;right:0;margin-top:48px}
|
||||
<?if ($themes1):?>
|
||||
span.wrap{display:inline-block;width:128px}
|
||||
select.clone{min-width:123px;margin-right:0}
|
||||
<?else:?>
|
||||
span.wrap{display:inline-block;width:150px}
|
||||
select.clone{min-width:145px;margin-right:0}
|
||||
<?endif;?>
|
||||
input.clone{margin-left:8px;margin-right:0}
|
||||
span.clone,i.clone{margin-right:4px}
|
||||
</style>
|
||||
<script>
|
||||
function toggleButton(button,id) {
|
||||
var disabled = true;
|
||||
switch (id) {
|
||||
case false:
|
||||
case true:
|
||||
disabled = id;
|
||||
break;
|
||||
default:
|
||||
$('select#'+id+' option').each(function(){if ($(this).prop('selected')==true) disabled = false;});
|
||||
}
|
||||
$('input#'+button).prop('disabled',disabled);
|
||||
}
|
||||
|
||||
var ctrl = "<span class='ctrl2 status <?=$tabbed?'vhshift':'vshift'?>'><a href='/Shares/Disk?name=<?=$prev?>' title='previous disk share'><button type='button' style='margin-right:4px'><i class='fa fa-chevron-left fa-fw'></i></button></a><a href='/Shares/Disk?name=<?=$next?>' title='next disk share'><button type='button'><i class='fa fa-chevron-right fa-fw'></i></button></a></span>";
|
||||
|
||||
$(function() {
|
||||
<?if ($tabbed):?>
|
||||
$('.tabs').append(ctrl);
|
||||
<?else:?>
|
||||
$('div[class=title]:first').append(ctrl);
|
||||
<?endif;?>
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,47 @@
|
||||
Menu="Shares:2"
|
||||
Title="Disk Shares"
|
||||
Tag="user-circle-o"
|
||||
Cond="_var($var,'fsState')!='Stopped' && _var($var,'shareDisk')!='no'"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<style>
|
||||
table.share_status thead tr td:first-child{width:15%}
|
||||
table.share_status thead tr td:nth-child(n+3){width:10%}
|
||||
</style>
|
||||
|
||||
<table class="share_status">
|
||||
<thead><tr><td>_(Name)_</td><td>_(Comment)_</td><td>_(SMB)_</td><td>_(NFS)_</td><td>_(Type)_</td><td>_(Size)_</td><td>_(Free)_</td></tr></thead>
|
||||
<tbody id="disk_list"></tbody>
|
||||
</table>
|
||||
|
||||
<input id="compute-disks" type="button" value="_(Compute All)_" onclick="$(this).prop('disabled',true);diskList('',-1)">
|
||||
|
||||
:disk_list_help:
|
||||
|
||||
<script>
|
||||
function diskList(name,all) {
|
||||
timers.diskList = setTimeout(function(){$('div.spinner.fixed').show();},500);
|
||||
$.post('/webGui/include/DiskList.php',{compute:name,path:"<?=rawurlencode($path)?>",all:all},function(data){
|
||||
clearTimeout(timers.diskList);
|
||||
$('div.spinner.fixed').hide();
|
||||
$('#disk_list').html(data);
|
||||
if (all!=1) $('#compute-disks').prop('disabled',!data||data.indexOf('colspan=')!=-1);
|
||||
});
|
||||
}
|
||||
function computeDisk(name,status) {
|
||||
status.html("<i class='fa fa-circle-o-notch fa-spin'></i> _(Please wait)_...");
|
||||
diskList(name,1);
|
||||
}
|
||||
$(diskList('',0));
|
||||
</script>
|
||||
@@ -0,0 +1,252 @@
|
||||
Menu="OtherSettings"
|
||||
Title="Disk Settings"
|
||||
Icon="icon-disks"
|
||||
Tag="icon-disk"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
require_once "$docroot/webGui/include/Preselect.php";
|
||||
$events = explode('|',$var['smEvents'] ?? $numbers);
|
||||
|
||||
function displayTemp($temp) {
|
||||
global $display;
|
||||
return (is_numeric($temp) && _var($display,'unit')=='F') ? round(9/5*$temp)+32 : $temp;
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
span.code{display:inline-block;width:186px}
|
||||
</style>
|
||||
<script>
|
||||
function doDispatch(form) {
|
||||
var fields = {};
|
||||
<?if (_var($display,'unit')=='F'):?>
|
||||
form.display_hot.value = Math.round((form.display_hot.value-32)*5/9);
|
||||
form.display_max.value = Math.round((form.display_max.value-32)*5/9);
|
||||
<?endif;?>
|
||||
fields['#cfg'] = "/boot/config/plugins/dynamix/dynamix.cfg";
|
||||
fields['#cleanup'] = true;
|
||||
$(form).find('input[name^="display_"]').each(function(){fields[$(this).attr('name')] = $(this).val(); $(this).prop('disabled',true);});
|
||||
$.post('/webGui/include/Dispatcher.php',fields);
|
||||
}
|
||||
function prepareDiskSettings(form) {
|
||||
var events = [];
|
||||
for (var i=0; i < <?=count($preselect)?>; i++) {
|
||||
if (form.elements['at'+i].checked) events.push(form.elements['at'+i].value);
|
||||
form.elements['at'+i].disabled = true;
|
||||
}
|
||||
var custom = form.smCustom.value.trim();
|
||||
var custom = custom.length ? custom.split(',') : [];
|
||||
for (var i=0; i < custom.length; i++) events.push(custom[i].trim());
|
||||
form.smEvents.value = events.join('|');
|
||||
if (form.smEvents.value == '<?=$numbers?>') form.smEvents.value = '';
|
||||
if (form.smLevel.value == 1.00) form.smLevel.value = '';
|
||||
}
|
||||
function setIndex(form) {
|
||||
form.smIndex.value = form.smType.selectedIndex;
|
||||
}
|
||||
</script>
|
||||
|
||||
<form markdown="1" method="POST" action="/update.htm" target="progressFrame" onsubmit="doDispatch(this)">
|
||||
_(Enable auto start)_:
|
||||
: <select name="startArray" size="1">
|
||||
<?=mk_option($var['startArray'], "no", _('No'))?>
|
||||
<?=mk_option($var['startArray'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:disk_enable_autostart_help:
|
||||
|
||||
_(Default spin down delay)_:
|
||||
: <select name="spindownDelay" size="1">
|
||||
<?=mk_option($var['spindownDelay'], "0", _('Never'))?>
|
||||
<?=mk_option($var['spindownDelay'], "15", "15 "._('minutes'))?>
|
||||
<?=mk_option($var['spindownDelay'], "30", "30 "._('minutes'))?>
|
||||
<?=mk_option($var['spindownDelay'], "45", "45 "._('minutes'))?>
|
||||
<?=mk_option($var['spindownDelay'], "1", "1 "._('hour'))?>
|
||||
<?=mk_option($var['spindownDelay'], "2", "2 "._('hours'))?>
|
||||
<?=mk_option($var['spindownDelay'], "3", "3 "._('hours'))?>
|
||||
<?=mk_option($var['spindownDelay'], "4", "4 "._('hours'))?>
|
||||
<?=mk_option($var['spindownDelay'], "5", "5 "._('hours'))?>
|
||||
<?=mk_option($var['spindownDelay'], "6", "6 "._('hours'))?>
|
||||
<?=mk_option($var['spindownDelay'], "7", "7 "._('hours'))?>
|
||||
<?=mk_option($var['spindownDelay'], "8", "8 "._('hours'))?>
|
||||
<?=mk_option($var['spindownDelay'], "9", "9 "._('hours'))?>
|
||||
</select>
|
||||
|
||||
:disk_spindown_delay_help:
|
||||
|
||||
_(Enable spinup groups)_:
|
||||
: <select name="spinupGroups" size="1">
|
||||
<?=mk_option($var['spinupGroups'], "no", _('No'))?>
|
||||
<?=mk_option($var['spinupGroups'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:disk_spinup_groups_help:
|
||||
|
||||
_(Default file system)_:
|
||||
: <select name="defaultFsType" size="1">
|
||||
<?=mk_option($var['defaultFsType'], "xfs", _('xfs'));?>
|
||||
<?=mk_option($var['defaultFsType'], "zfs", _('zfs'));?>
|
||||
<?=mk_option($var['defaultFsType'], "btrfs", _('btrfs'));?>
|
||||
<?=mk_option($var['defaultFsType'], "reiserfs", _('reiserfs'));?>
|
||||
<?=mk_option($var['defaultFsType'], "luks:xfs", _('xfs')." - "._('encrypted'));?>
|
||||
<?=mk_option($var['defaultFsType'], "luks:zfs", _('zfs')." - "._('encrypted'));?>
|
||||
<?=mk_option($var['defaultFsType'], "luks:btrfs", _('btrfs')." - "._('encrypted'));?>
|
||||
<?=mk_option($var['defaultFsType'], "luks:reiserfs", _('reiserfs')." - "._('encrypted'));?>
|
||||
</select>
|
||||
|
||||
:disk_default_file_system_help:
|
||||
|
||||
_(Shutdown time-out)_:
|
||||
: <input type="text" name="shutdownTimeout" maxlength="10" value="<?=$var['shutdownTimeout']?>" class="narrow">
|
||||
|
||||
:disk_shutdown_timeout_help:
|
||||
|
||||
_(Tunable (poll_attributes))_:
|
||||
: <input type="text" name="poll_attributes" maxlength="10" value="<?=$var['poll_attributes']?>" class="narrow"><?=_($var['poll_attributes_status'])?>
|
||||
|
||||
:disk_tunable_poll_attributes_help:
|
||||
|
||||
_(Tunable (enable NCQ))_:
|
||||
: <select name="queueDepth" size="1">
|
||||
<?=mk_option($var['queueDepth'], "auto", _('Auto'))?>
|
||||
<?=mk_option($var['queueDepth'], "1", _('No'))?>
|
||||
</select>
|
||||
|
||||
:disk_tunable_enable_ncq_help:
|
||||
|
||||
_(Tunable (nr_requests))_:
|
||||
: <input type="text" name="nr_requests" maxlength="10" value="<?=$var['nr_requests']?>" class="narrow"><?=_($var['nr_requests_status'])?>
|
||||
|
||||
:disk_tunable_nr_requests_help:
|
||||
|
||||
_(Tunable (scheduler))_:
|
||||
: <select name="md_scheduler" size="1">
|
||||
<?=mk_option($var['md_scheduler'], "auto", _('Auto'))?>
|
||||
<?=mk_option($var['md_scheduler'], "mq-deadline", _('mq-deadline'))?>
|
||||
<?=mk_option($var['md_scheduler'], "kyber", _('kyber'))?>
|
||||
<?=mk_option($var['md_scheduler'], "bfq", _('bfq'))?>
|
||||
<?=mk_option($var['md_scheduler'], "none", _('none'))?>
|
||||
</select>
|
||||
|
||||
:disk_tunable_scheduler_help:
|
||||
|
||||
_(Tunable (md_num_stripes))_:
|
||||
: <input type="text" name="md_num_stripes" maxlength="10" value="<?=$var['md_num_stripes']?>" class="narrow"><?=_($var['md_num_stripes_status'])?>
|
||||
|
||||
:disk_tunable_md_num_stripes_help:
|
||||
|
||||
_(Tunable (md_queue_limit))_:
|
||||
: <input type="text" name="md_queue_limit" maxlength="10" value="<?=$var['md_queue_limit']?>" class="narrow"><?=_($var['md_queue_limit_status'])?>
|
||||
|
||||
:disk_tunable_md_queue_limit_help:
|
||||
|
||||
_(Tunable (md_sync_limit))_:
|
||||
: <input type="text" name="md_sync_limit" maxlength="10" value="<?=$var['md_sync_limit']?>" class="narrow"><?=_($var['md_sync_limit_status'])?>
|
||||
|
||||
:disk_tunable_md_sync_limit_help:
|
||||
|
||||
_(Tunable (md_write_method))_:
|
||||
: <select name="md_write_method" size="1">
|
||||
<?=mk_option($var['md_write_method'], "auto", _('Auto'))?>
|
||||
<?=mk_option($var['md_write_method'], "0", _('read/modify/write'))?>
|
||||
<?=mk_option($var['md_write_method'], "1", _('reconstruct write'))?>
|
||||
</select>
|
||||
|
||||
:disk_tunable_md_write_method_help:
|
||||
|
||||
_(Default warning disk utilization threshold)_ (%):
|
||||
: <input type="number" min="0" max="100" name="display_warning" class="narrow" value="<?=_var($display,'warning')?>">
|
||||
|
||||
:disk_default_warning_utilization_help:
|
||||
|
||||
_(Default critical disk utilization threshold)_ (%):
|
||||
: <input type="number" min="0" max="100" name="display_critical" class="narrow" value="<?=_var($display,'critical')?>">
|
||||
|
||||
:disk_default_critical_utilization_help:
|
||||
|
||||
_(Default warning disk temperature threshold)_ (°<?=_var($display,'unit','C')?>):
|
||||
: <input type="number" min="0" max="300" name="display_hot" class="narrow" value="<?=displayTemp(_var($display,'hot'))?>">
|
||||
|
||||
:disk_default_warning_temperature_help:
|
||||
|
||||
_(Default critical disk temperature threshold)_ (°<?=_var($display,'unit','C')?>):
|
||||
: <input type="number" min="0" max="300" name="display_max" class="narrow" value="<?=displayTemp(_var($display,'max'))?>">
|
||||
|
||||
:disk_default_critical_temperature_help:
|
||||
|
||||
|
||||
: <input type="submit" name="changeDisk" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
|
||||
<div class="title"><span class="left"><i class="title fa fa-plus-square"></i>_(Global SMART Settings)_</span></div>
|
||||
|
||||
<form markdown="1" name="smart_settings" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareDiskSettings(this)">
|
||||
<input type="hidden" name="#file" value="/boot/config/smart-all.cfg">
|
||||
<input type="hidden" name="#include" value="webGui/include/update.smart.php">
|
||||
<input type="hidden" name="#cleanup" value="true">
|
||||
<input type="hidden" name="#top" value="1">
|
||||
<input type="hidden" name="smEvents" value="">
|
||||
<input type="hidden" name="smIndex" value="0">
|
||||
_(Default SMART notification value)_:
|
||||
: <select name="smSelect" size="1">
|
||||
<?=mk_option(_var($var,'smSelect'), "0", _('Raw'))?>
|
||||
<?=mk_option(_var($var,'smSelect'), "1", _('Normalized'))?>
|
||||
</select>
|
||||
|
||||
:disk_default_smart_notification_help:
|
||||
|
||||
_(Default SMART notification tolerance level)_:
|
||||
: <select name="smLevel" size="1">
|
||||
<?=mk_option(_var($var,'smLevel'), "1.00", _('Absolute'))?>
|
||||
<?=mk_option(_var($var,'smLevel'), "1.05", "5%")?>
|
||||
<?=mk_option(_var($var,'smLevel'), "1.10", "10%")?>
|
||||
<?=mk_option(_var($var,'smLevel'), "1.15", "15%")?>
|
||||
<?=mk_option(_var($var,'smLevel'), "1.20", "20%")?>
|
||||
<?=mk_option(_var($var,'smLevel'), "1.25", "25%")?>
|
||||
<?=mk_option(_var($var,'smLevel'), "1.50", "50%")?>
|
||||
</select>
|
||||
|
||||
:disk_default_smart_tolerance_help:
|
||||
|
||||
_(Default SMART controller type)_:
|
||||
: <select name="smType" size="1" onchange="setIndex(this.form)">
|
||||
<?=mk_option(_var($var,'smType'), "", _('Automatic'))?>
|
||||
<?=mk_option(_var($var,'smType'), "-d ata", "ATA")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d nvme", "NVMe")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d sat", "SAT")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d scsi", "SCSI")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d 3ware", "3Ware")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d aacraid", "Adaptec")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d areca", "Areca")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d hpt", "HighPoint")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d cciss", "HP cciss")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d marvell", "Marvell")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d megaraid", "MegaRAID")?>
|
||||
</select>
|
||||
|
||||
:disk_default_smart_controller_help:
|
||||
|
||||
_(Default SMART attribute notifications)_:
|
||||
: <input type="text" name="smCustom" value="<?=_var($var,'smCustom')?>" class="narrow">_(Custom attributes (use comma to separate numbers))_
|
||||
|
||||
<?for ($x = 0; $x < count($preselect); $x++):?>
|
||||
|
||||
: <input type="checkbox" name="at<?=$x?>" value="<?=_var($preselect[$x],'code')?>"<?=in_array(_var($preselect[$x],'code'),$events)?' checked':''?>><span class="code">_(Attribute)_ = <?=_var($preselect[$x],'code')?></span><?=_var($preselect[$x],'text')?>
|
||||
<?endfor;?>
|
||||
|
||||
:disk_default_smart_attribute_help:
|
||||
|
||||
<input type="submit" name="#default" value="_(Default)_">
|
||||
: <input type="submit" name="#apply" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
@@ -0,0 +1,340 @@
|
||||
Menu="UserPreferences"
|
||||
Title="Display Settings"
|
||||
Icon="icon-display"
|
||||
Tag="desktop"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$void = "<img src='/webGui/images/banner.png' id='image' width='330' height='30' onclick='$("#drop").click()' style='cursor:pointer' title='_(Click to select PNG file)_'>";
|
||||
$icon = "<i class='fa fa-trash top' title='_(Restore default image)_' onclick='restore()'></i>";
|
||||
$plugins = '/var/log/plugins';
|
||||
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
?>
|
||||
<style>
|
||||
span#dropbox{margin-right:20px;}
|
||||
i.top{position:relative;padding-left:4px;cursor:pointer;}
|
||||
select.fixed{max-width:166px}
|
||||
</style>
|
||||
|
||||
<script src="<?autov('/webGui/javascript/jquery.filedrop.js')?>"></script>
|
||||
<script>
|
||||
var path = '/boot/config/plugins/dynamix';
|
||||
var filename = '';
|
||||
|
||||
function restore() {
|
||||
// restore original image and activate APPLY button
|
||||
$('#dropbox').html("<?=$void?>");
|
||||
$('select[name="banner"]').trigger('change');
|
||||
filename = 'reset';
|
||||
}
|
||||
function upload() {
|
||||
// save or delete upload when APPLY is pressed
|
||||
if (filename=='reset') {
|
||||
$.post("/webGui/include/FileUpload.php",{cmd:'delete',path:path,filename:'banner.png'});
|
||||
} else if (filename) {
|
||||
$.post("/webGui/include/FileUpload.php",{cmd:'save',path:path,filename:filename,output:'banner.png'});
|
||||
}
|
||||
}
|
||||
function presetTime(form) {
|
||||
var system = form.date.selectedIndex==0;
|
||||
if (system) form.time.selectedIndex = 0;
|
||||
form.time.disabled = system;
|
||||
}
|
||||
function presetBanner(form) {
|
||||
if (form.banner.selectedIndex == 0) $('.js-bannerSettings').hide(); else $('.js-bannerSettings').show();
|
||||
}
|
||||
function presetRefresh(form) {
|
||||
for (var i=0,item; item=form.refresh.options[i]; i++) item.value *= -1;
|
||||
}
|
||||
function presetPassive(index) {
|
||||
if (index==0) $('#passive').hide(); else $('#passive').show();
|
||||
}
|
||||
function updateDirection(lang) {
|
||||
// var rtl = ['ar_AR','fa_FA'].includes(lang) ? "dir='rtl' " : "";
|
||||
// RTL display is not giving the desired results, we keep LTR
|
||||
var rtl = "";
|
||||
$('input[name="rtl"]').val(rtl);
|
||||
}
|
||||
|
||||
$(function() {
|
||||
var dropbox = $('#dropbox');
|
||||
// attach the drag-n-drop feature to the 'dropbox' element
|
||||
dropbox.filedrop({
|
||||
maxfiles:1,
|
||||
maxfilesize:512, // KB
|
||||
data: {"csrf_token": "<?=$var['csrf_token']?>"},
|
||||
url:'/webGui/include/FileUpload.php',
|
||||
beforeEach:function(file) {
|
||||
if (!file.type.match(/^image\/.*/)) {
|
||||
swal({title:"_(Warning)_",text:"_(Only PNG images are allowed)_!",type:"warning",html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
},
|
||||
error: function(err, file, i) {
|
||||
switch (err) {
|
||||
case 'BrowserNotSupported':
|
||||
swal({title:"_(Browser error)_",text:"_(Your browser does not support HTML5 file uploads)_!",type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
break;
|
||||
case 'TooManyFiles':
|
||||
swal({title:"_(Too many files)_",text:"_(Please select one file only)_!",html:true,type:"error"});
|
||||
break;
|
||||
case 'FileTooLarge':
|
||||
swal({title:"_(File too large)_",text:"_(Maximum file upload size is 512K)_ (524,288 _(bytes)_)",type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
break;
|
||||
}
|
||||
},
|
||||
uploadStarted:function(i,file,count) {
|
||||
var image = $('img', $(dropbox));
|
||||
var reader = new FileReader();
|
||||
image.width = 330;
|
||||
image.height = 30;
|
||||
reader.onload = function(e){image.attr('src',e.target.result);};
|
||||
reader.readAsDataURL(file);
|
||||
},
|
||||
uploadFinished:function(i,file,response) {
|
||||
if (response == 'OK 200') {
|
||||
if (!filename || filename=='reset') $(dropbox).append("<?=$icon?>");
|
||||
$('select[name="banner"]').trigger('change');
|
||||
filename = file.name;
|
||||
} else {
|
||||
swal({title:"_(Upload error)_",text:response,type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
}
|
||||
}
|
||||
});
|
||||
// simulate a drop action when manual file selection is done
|
||||
$('#drop').bind('change', function(e) {
|
||||
var files = e.target.files;
|
||||
if ($('#dropbox').triggerHandler({type:'drop',dataTransfer:{files:files}})==false) e.stopImmediatePropagation();
|
||||
});
|
||||
presetTime(document.display_settings);
|
||||
presetBanner(document.display_settings);
|
||||
});
|
||||
</script>
|
||||
|
||||
:display_settings_help:
|
||||
|
||||
<form markdown="1" name="display_settings" method="POST" action="/update.php" target="progressFrame" onsubmit="upload()">
|
||||
<input type="hidden" name="#file" value="dynamix/dynamix.cfg">
|
||||
<input type="hidden" name="#section" value="display">
|
||||
<input type="hidden" name="rtl" value="<?=$display['rtl']?>">
|
||||
_(Language)_:
|
||||
: <select name="locale" class="fixed" onchange="updateDirection(this.value)">
|
||||
<?echo mk_option($display['locale'], "","English");
|
||||
foreach (glob("$plugins/lang-*.xml",GLOB_NOSORT) as $xml_file) {
|
||||
$lang = language('Language', $xml_file);
|
||||
$home = language('LanguageLocal', $xml_file);
|
||||
$name = language('LanguagePack', $xml_file);
|
||||
echo mk_option($display['locale'], $name, "$home ($lang)");
|
||||
}
|
||||
?></select>
|
||||
|
||||
_(Font size)_:
|
||||
: <select name="font" id='font'>
|
||||
<?=mk_option($display['font'], "50",_('Very small'))?>
|
||||
<?=mk_option($display['font'], "56.25",_('Small'))?>
|
||||
<?=mk_option($display['font'], "",_('Normal'))?>
|
||||
<?=mk_option($display['font'], "68.75",_('Large'))?>
|
||||
<?=mk_option($display['font'], "75",_('Very large'))?>
|
||||
<?=mk_option($display['font'], "80",_('Huge'))?>
|
||||
</select>
|
||||
|
||||
:display_font_size_help:
|
||||
|
||||
_(Terminal font size)_:
|
||||
: <select name="tty" id="tty">
|
||||
<?=mk_option($display['tty'], "11",_('Very small'))?>
|
||||
<?=mk_option($display['tty'], "13",_('Small'))?>
|
||||
<?=mk_option($display['tty'], "15",_('Normal'))?>
|
||||
<?=mk_option($display['tty'], "17",_('Large'))?>
|
||||
<?=mk_option($display['tty'], "19",_('Very large'))?>
|
||||
<?=mk_option($display['tty'], "21",_('Huge'))?>
|
||||
</select>
|
||||
|
||||
:display_tty_size_help:
|
||||
|
||||
_(Date format)_:
|
||||
: <select name="date" onchange="presetTime(this.form)">
|
||||
<?=mk_option($display['date'], "%c","_(System Setting)_")?>
|
||||
<?=mk_option($display['date'], "%A, %Y %B %e",_('Day, YYYY Month D'))?>
|
||||
<?=mk_option($display['date'], "%A, %e %B %Y",_('Day, D Month YYYY'))?>
|
||||
<?=mk_option($display['date'], "%A, %B %e, %Y",_('Day, Month D, YYYY'))?>
|
||||
<?=mk_option($display['date'], "%A, %m/%d/%Y",_('Day, MM/DD/YYYY'))?>
|
||||
<?=mk_option($display['date'], "%A, %d-%m-%Y",_('Day, DD-MM-YYYY'))?>
|
||||
<?=mk_option($display['date'], "%A, %d.%m.%Y",_('Day, DD.MM.YYYY'))?>
|
||||
<?=mk_option($display['date'], "%A, %Y-%m-%d",_('Day, YYYY-MM-DD'))?>
|
||||
</select>
|
||||
|
||||
_(Time format)_:
|
||||
: <select name="time">
|
||||
<?=mk_option($display['time'], "%I:%M %p",_('12 hours'))?>
|
||||
<?=mk_option($display['time'], "%R",_('24 hours'))?>
|
||||
</select>
|
||||
|
||||
_(Number format)_:
|
||||
: <select name="number">
|
||||
<?=mk_option($display['number'], ".,",_('[D] dot : [G] comma'))?>
|
||||
<?=mk_option($display['number'], ". ",_('[D] dot : [G] space'))?>
|
||||
<?=mk_option($display['number'], ".",_('[D] dot : [G] none'))?>
|
||||
<?=mk_option($display['number'], ",.",_('[D] comma : [G] dot'))?>
|
||||
<?=mk_option($display['number'], ", ",_('[D] comma : [G] space'))?>
|
||||
<?=mk_option($display['number'], ",",_('[D] comma : [G] none'))?>
|
||||
</select>
|
||||
|
||||
_(Number scaling)_:
|
||||
: <select name="scale">
|
||||
<?=mk_option($display['scale'], "-1",_('Automatic'))?>
|
||||
<?=mk_option($display['scale'], "0",_('Disabled'))?>
|
||||
<?=mk_option($display['scale'], "1",_('KB'))?>
|
||||
<?=mk_option($display['scale'], "2",_('MB'))?>
|
||||
<?=mk_option($display['scale'], "3",_('GB'))?>
|
||||
<?=mk_option($display['scale'], "4",_('TB'))?>
|
||||
<?=mk_option($display['scale'], "5",_('PB'))?>
|
||||
</select>
|
||||
|
||||
_(Page view)_:
|
||||
: <select name="tabs">
|
||||
<?=mk_option($display['tabs'], "0",_('Tabbed'))?>
|
||||
<?=mk_option($display['tabs'], "1",_('Non-tabbed'))?>
|
||||
</select>
|
||||
|
||||
:display_page_view_help:
|
||||
|
||||
_(Placement of Users menu)_:
|
||||
: <select name="users">
|
||||
<?=mk_option($display['users'], "Tasks:3",_('Header menu'))?>
|
||||
<?=mk_option($display['users'], "UserPreferences",_('Settings menu'))?>
|
||||
</select>
|
||||
|
||||
:display_users_menu_help:
|
||||
|
||||
_(Listing height)_:
|
||||
: <select name="resize">
|
||||
<?=mk_option($display['resize'], "0",_('Automatic'))?>
|
||||
<?=mk_option($display['resize'], "1",_('Fixed'))?>
|
||||
</select>
|
||||
|
||||
:display_listing_height_help:
|
||||
|
||||
_(Display device name)_:
|
||||
: <select name="raw">
|
||||
<?=mk_option($display['raw'], "",_('Normalized'))?>
|
||||
<?=mk_option($display['raw'], "1",_('Raw'))?>
|
||||
</select>
|
||||
|
||||
_(Display world-wide-name in device ID)_:
|
||||
: <select name="wwn">
|
||||
<?=mk_option($display['wwn'], "0",_('Disabled'))?>
|
||||
<?=mk_option($display['wwn'], "1",_('Automatic'))?>
|
||||
</select>
|
||||
|
||||
:display_wwn_device_id_help:
|
||||
|
||||
_(Display array totals)_:
|
||||
: <select name="total">
|
||||
<?=mk_option($display['total'], "0",_('No'))?>
|
||||
<?=mk_option($display['total'], "1",_('Yes'))?>
|
||||
</select>
|
||||
|
||||
_(Show array utilization indicator)_:
|
||||
: <select name="usage">
|
||||
<?=mk_option($display['usage'], "0",_('No'))?>
|
||||
<?=mk_option($display['usage'], "1",_('Yes'))?>
|
||||
</select>
|
||||
|
||||
_(Temperature unit)_:
|
||||
: <select name="unit">
|
||||
<?=mk_option($display['unit'], "C",_('Celsius'))?>
|
||||
<?=mk_option($display['unit'], "F",_('Fahrenheit'))?>
|
||||
</select>
|
||||
|
||||
:display_temperature_unit_help:
|
||||
|
||||
_(Show Dashboard apps)_:
|
||||
: <select name="dashapps">
|
||||
<?=mk_option($display['dashapps'], "icons",_('Docker + VMs'))?>
|
||||
<?=mk_option($display['dashapps'], "docker",_('Docker only'))?>
|
||||
<?=mk_option($display['dashapps'], "vms",_('VMs only'))?>
|
||||
<?=mk_option($display['dashapps'], "none",_('None'))?>
|
||||
</select>
|
||||
|
||||
_(Dynamix color theme)_:
|
||||
: <select name="theme">
|
||||
<?foreach (glob("$docroot/webGui/styles/dynamix-*.css") as $themes):?>
|
||||
<?$theme = substr(basename($themes,'.css'),8);?>
|
||||
<?=mk_option($display['theme'], $theme, _(ucfirst($theme)))?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
_(Used / Free columns)_:
|
||||
: <select name="text">
|
||||
<?=mk_option($display['text'], "0",_('Text'))?>
|
||||
<?=mk_option($display['text'], "1",_('Bar (gray)'))?>
|
||||
<?=mk_option($display['text'], "2",_('Bar (color)'))?>
|
||||
<?=mk_option($display['text'], "10",_('Text - Bar (gray)'))?>
|
||||
<?=mk_option($display['text'], "20",_('Text - Bar (color)'))?>
|
||||
<?=mk_option($display['text'], "11",_('Bar (gray) - Text'))?>
|
||||
<?=mk_option($display['text'], "21",_('Bar (color) - Text'))?>
|
||||
</select>
|
||||
|
||||
_(Header custom text color)_:
|
||||
: <input type="text" class="narrow" name="header" value="<?=$display['header']?>" maxlength="6" pattern="([0-9a-fA-F]{3}){1,2}" title="_(HTML color code of 3 or 6 hexadecimal digits)_">
|
||||
|
||||
:display_custom_text_color_help:
|
||||
|
||||
_(Header custom secondary text color)_:
|
||||
: <input type="text" class="narrow" name="headermetacolor" value="<?=$display['headermetacolor']?>" maxlength="6" pattern="([0-9a-fA-F]{3}){1,2}" title="_(HTML color code of 3 or 6 hexadecimal digits)_">
|
||||
|
||||
_(Header custom background color)_:
|
||||
: <input type="text" class="narrow" name="background" value="<?=$display['background']?>" maxlength="6" pattern="([0-9a-fA-F]{3}){1,2}" title="_(HTML color code of 3 or 6 hexadecimal digits)_">
|
||||
|
||||
:display_custom_background_color_help:
|
||||
|
||||
_(Header show description)_:
|
||||
: <select name="headerdescription">
|
||||
<?=mk_option($display['headerdescription'], "yes",_('Yes'))?>
|
||||
<?=mk_option($display['headerdescription'], "no",_('No'))?>
|
||||
</select>
|
||||
|
||||
_(Show banner)_:
|
||||
: <select name="banner" onchange="presetBanner(this.form)">
|
||||
<?=mk_option($display['banner'], "",_('No'))?>
|
||||
<?=mk_option($display['banner'], "image",_('Yes'))?>
|
||||
</select>
|
||||
|
||||
<div class="js-bannerSettings" markdown="1" style="display:none">
|
||||
_(Custom banner)_:
|
||||
<input type="hidden" name="#custom" value="">
|
||||
: <span id="dropbox">
|
||||
<?if (file_exists($banner)):?>
|
||||
<img src="<?=autov($banner)?>" width="330" height="30" onclick="$('#drop').click()" style="cursor:pointer" title="_(Click to select PNG file)_"><?=$icon?>
|
||||
<?else:?>
|
||||
<?=$void?>
|
||||
<?endif;?>
|
||||
</span><em>_(Drag-n-drop a PNG file or click the image at the left)_.</em><input type="file" id="drop" accept="image/*" style="display:none">
|
||||
|
||||
:display_custom_banner_help:
|
||||
</div>
|
||||
|
||||
<div class="js-bannerSettings" markdown="1" style="display:none">
|
||||
_(Show banner background color fade)_:
|
||||
: <select name="showBannerGradient">
|
||||
<?=mk_option($display['showBannerGradient'], "no",_('No'))?>
|
||||
<?=mk_option($display['showBannerGradient'], "yes",_('Yes'))?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<input type="submit" name="#default" value="_(Default)_" onclick="filename='reset'">
|
||||
: <input type="submit" name="#apply" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
@@ -0,0 +1,861 @@
|
||||
Menu="NetworkSettings:100"
|
||||
Title="_(Interface)_ eth0"
|
||||
Tag="icon-ethernet"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$members = parse_ini_file('state/network.ini',true);
|
||||
|
||||
$build = false;
|
||||
$template = "$docroot/webGui/EthX.page";
|
||||
$ini = '/var/local/emhttp/network.ini';
|
||||
|
||||
$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})?)";
|
||||
$width = [166,300];
|
||||
|
||||
// get available ethernet ports (excluding eth0)
|
||||
exec("ls --indicator-style=none /sys/class/net|grep -P '^eth[1-9][0-9]*$'",$ports);
|
||||
|
||||
function locked($source,$port) {
|
||||
global $members;
|
||||
foreach ($members as $member => $value) {
|
||||
if ($member == $source) continue;
|
||||
if ($value['BONDING']=='yes' && in_array($port,explode(',',$value['BONDNICS']))) return $value['BONDNAME'].' '.$member;
|
||||
if ($value['BRIDGING']=='yes' && in_array($port,explode(',',$value['BRNICS']))) return $value['BRNAME'].' '.$member;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function vlanID($cfg) {
|
||||
return array_filter($cfg,function($key){return strpos($key,'VLANID:')===0;},ARRAY_FILTER_USE_KEY);
|
||||
}
|
||||
function index($key) {
|
||||
return filter_var($key,FILTER_SANITIZE_NUMBER_INT);
|
||||
}
|
||||
// remove non-existing ethernet ports
|
||||
foreach (glob("$docroot/webGui/Eth[1-9]*.page",GLOB_NOSORT) as $port) {
|
||||
if (!in_array(strtolower(basename($port,'.page')), $ports)) {
|
||||
@unlink($port);
|
||||
$build = true;
|
||||
}
|
||||
}
|
||||
// add new ethernet ports
|
||||
foreach ($ports as $ethX) {
|
||||
$file = "$docroot/webGui/".ucfirst($ethX).".page";
|
||||
if (!file_exists($file)) {
|
||||
$X = filter_var($ethX,FILTER_SANITIZE_NUMBER_INT);
|
||||
file_put_contents($file,str_replace(['parentname:nnn','tabX','bondX','brX','ethX'],['NetworkSettings:'.($X+100),'tab'.($X+1),'bond'.$X,'br'.$X,$ethX],file_get_contents($template)));
|
||||
$build = true;
|
||||
}
|
||||
}
|
||||
// enable interface only when VMs and Docker are stopped
|
||||
$service = exec("pgrep libvirt") ? _('VM manager') : '';
|
||||
$service .= exec("pgrep docker") ? ($service ? ' '._('and').' ' : '')._('Docker service') : '';
|
||||
|
||||
// eth0 port status
|
||||
$no_eth0 = exec("ip link show eth0|grep -Pom1 '(NO-CARRIER|state DOWN)'");
|
||||
|
||||
// get VLAN interfaces
|
||||
$vlan_eth0 = $sort_eth0 = [];
|
||||
if (isset($eth0)) foreach (vlanID($eth0) as $key => $val) {$vlan_eth0[] = index($key); $sort_eth0[] = (int)$val;}
|
||||
array_multisort($sort_eth0,$vlan_eth0);
|
||||
?>
|
||||
<style>
|
||||
span.red{color:#E68A00}
|
||||
span.blue{color:#00529B}
|
||||
span.green{color:#4F8A10}
|
||||
span.vshift{margin-top:0!important}
|
||||
input.gap{margin-right:6px}
|
||||
input.form{font-size:1rem;padding:5px 10px;margin-left:10px}
|
||||
div.shade-white{background-color:#ededed;margin-top:10px;padding:8px 0 3px 0}
|
||||
div.shade-black{background-color:#212121;margin-top:10px;padding:8px 0 3px 0}
|
||||
div.shade-azure{background-color:#edeaef;margin-top:10px;padding:8px 0 3px 0}
|
||||
div.shade-gray{background-color:#121510;margin-top:10px;padding:8px 0 3px 0}
|
||||
select.slim{min-width:47px;margin-left:4px}
|
||||
input.slim{width:32px;margin-left:8px}
|
||||
</style>
|
||||
<script>
|
||||
<?if ($build):?>
|
||||
refresh(); // automatically include new ethernet ports
|
||||
<?endif;?>
|
||||
Array.prototype.same = function(){return this.sort().filter(function(v,i,o){return i&&v===o[i-1]?v:0;}).length;}
|
||||
|
||||
function prepareSettings(form) {
|
||||
var metrics = [];
|
||||
var metrics6 = [];
|
||||
if ($(form).find('input[name="#arg[1]"]').val()=='none') return true;
|
||||
$(form).find('input[name^="METRIC:"]').each(function(){if($(this).val()>0) metrics.push($(this).val());});
|
||||
$(form).find('input[name^="METRIC6:"]').each(function(){if($(this).val()>0) metrics6.push($(this).val());});
|
||||
if (metrics.same() || metrics6.same()) {
|
||||
swal({title:'Duplicate metrics',text:'List of default gateways contains duplicate metric values',type:'error',html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
if (form.TYPE.value == 'access') {
|
||||
$(form).find('input[name^="VLANID:"]').prop('disabled',false).val('');
|
||||
$(form).find('input[name^="DESCRIPTION:"]').not('input[name$=":0"]').prop('disabled',false).val('');
|
||||
$(form).find('select[name^="PROTOCOL:"]').not('select[name$=":0"]').prop('disabled',false).val('');
|
||||
$(form).find('select[name^="USE_DHCP:"]').not('select[name$=":0"]').prop('disabled',false).val('');
|
||||
$(form).find('select[name^="USE_DHCP6:"]').not('select[name$=":0"]').prop('disabled',false).val('');
|
||||
$(form).find('input[name^="IPADDR:"]').not('input[name$=":0"]').prop('disabled',false).val('');
|
||||
$(form).find('input[name^="IPADDR6:"]').not('input[name$=":0"]').prop('disabled',false).val('');
|
||||
$(form).find('select[name^="NETMASK:"]').not('select[name$=":0"]').prop('disabled',false).val('');
|
||||
$(form).find('input[name^="NETMASK6:"]').not('input[name$=":0"]').prop('disabled',false).val('');
|
||||
$(form).find('select[name^="GATEWAY:"]').not('select[name$=":0"]').prop('disabled',false).val('');
|
||||
$(form).find('input[name^="GATEWAY6:"]').not('input[name$=":0"]').prop('disabled',false).val('');
|
||||
$(form).find('input[name^="METRIC:"]').not('input[name$=":0"]').prop('disabled',false).val('');
|
||||
$(form).find('select[name^="PRIVACY6:"]').not('select[name$=":0"]').prop('disabled',false).val('');
|
||||
} else {
|
||||
var vlans = [];
|
||||
$(form).find('input[name^="VLANID:"]').each(function(){vlans.push($(this).val());});
|
||||
if (vlans.same()) {
|
||||
swal({title:"_(VLAN assignment mismatch)_",text:"_(List of VLANs contains duplicate VLAN numbers)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var member = '';
|
||||
for (var i=0,item; item=form.BONDNICS.options[i]; i++) {
|
||||
if (item.selected) {
|
||||
if (member.length) member += ',';
|
||||
member += item.value;
|
||||
item.selected = false;
|
||||
}
|
||||
}
|
||||
item = form.BONDNICS.options[0];
|
||||
item.value = member;
|
||||
item.selected = true;
|
||||
item.disabled = false;
|
||||
var member = '';
|
||||
for (var i=0,item; item=form.BRNICS.options[i]; i++) {
|
||||
if (item.selected) {
|
||||
if (member.length) member += ',';
|
||||
member += item.value;
|
||||
item.selected = false;
|
||||
}
|
||||
}
|
||||
item = form.BRNICS.options[0];
|
||||
item.value = form.BONDING.value=='yes' ? form.BONDNAME.value : member;
|
||||
item.selected = true;
|
||||
item.disabled = false;
|
||||
if (member.indexOf(',')>0) form.BRSTP.value = 'yes';
|
||||
$(form).find('select[name^="PROTOCOL:"]').each(function() {
|
||||
var protocol = $(this).val() || 'ipv4';
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
if (protocol == 'ipv6') {
|
||||
$(form).find('input[name="IPADDR:'+i+'"]').prop('disabled',false).val('');
|
||||
$(form).find('select[name="NETMASK:'+i+'"]').prop('disabled',false).val('');
|
||||
$(form).find('input[name="GATEWAY:'+i+'"]').prop('disabled',false).val('');
|
||||
$(form).find('input[name="METRIC:'+i+'"]').prop('disabled',false).val('');
|
||||
if (i==0) $(form).find('input[name^="DNS_SERVER"]').prop('disabled',false).val('');
|
||||
}
|
||||
if (protocol == 'ipv4') {
|
||||
$(form).find('input[name="IPADDR6:'+i+'"]').prop('disabled',false).val('');
|
||||
$(form).find('input[name="NETMASK6:'+i+'"]').prop('disabled',false).val('');
|
||||
$(form).find('input[name="GATEWAY6:'+i+'"]').prop('disabled',false).val('');
|
||||
$(form).find('input[name="METRIC6:'+i+'"]').prop('disabled',false).val('');
|
||||
$(form).find('select[name="PRIVACY6:'+i+'"]').prop('disabled',false).val('');
|
||||
if (i==0) $(form).find('input[name^="DNS6_SERVER"]').prop('disabled',false).val('');
|
||||
}
|
||||
});
|
||||
$(form).find('select[name^="USE_DHCP:"]').each(function() {
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
var protocol = $(form).find('select[name="PROTOCOL:'+i+'"]').val() || 'ipv4';
|
||||
var metric = $(form).find('input[name="METRIC:'+i+'"]').val();
|
||||
if ($(this).prop('disabled')==false && $(this).val()=='yes') {
|
||||
if (protocol != 'ipv6') {
|
||||
$(form).find('input[name="IPADDR:'+i+'"]').val('_(Obtaining IPv4 address)_...');
|
||||
$(form).find('input[name="GATEWAY:'+i+'"]').val(metric!='0'?'_(Obtaining IPv4 gateway)_...':'');
|
||||
}
|
||||
} else if (protocol != 'ipv6' && $(this).val()=='yes') {
|
||||
$(form).find('input[name="IPADDR:'+i+'"]').prop('disabled',false).val('');
|
||||
$(form).find('input[name="GATEWAY:'+i+'"]').prop('disabled',false).val('');
|
||||
}
|
||||
});
|
||||
$(form).find('select[name^="USE_DHCP6:"]').each(function() {
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
var protocol = $(form).find('select[name="PROTOCOL:'+i+'"]').val() || 'ipv4';
|
||||
var metric = $(form).find('input[name="METRIC6:'+i+'"]').val();
|
||||
if ($(this).prop('disabled')==false && $(this).val()=='yes') {
|
||||
if (protocol != 'ipv4') {
|
||||
$(form).find('input[name="IPADDR6:'+i+'"]').val('_(Obtaining IPv6 address)_...');
|
||||
$(form).find('input[name="GATEWAY6:'+i+'"]').val(metric!='0'?'_(Obtaining IPv6 gateway)_...':'');
|
||||
}
|
||||
} else if (protocol != 'ipv4' && $(this).val()=='yes') {
|
||||
$(form).find('input[name="IPADDR6:'+i+'"]').prop('disabled',false).val('');
|
||||
$(form).find('input[name="GATEWAY6:'+i+'"]').prop('disabled',false).val('');
|
||||
}
|
||||
if ($(this).val()!='yes') $(form).find('input[name="PRIVACY6:'+i+'"]').prop('disabled',false).val('');
|
||||
});
|
||||
if (form.DHCP_KEEPRESOLV !== undefined && form.DHCP_KEEPRESOLV.value=='no') {
|
||||
form.DHCP_KEEPRESOLV.disabled = false;
|
||||
var protocol = $(form).find('select[name="PROTOCOL:0"]').val() || 'ipv4';
|
||||
if (protocol != 'ipv6') $(form).find('input[name^="DNS_SERVER"]').val('_(Obtaining DNSv4 server)_...');
|
||||
}
|
||||
if (form.DHCP6_KEEPRESOLV !== undefined && form.DHCP6_KEEPRESOLV.value=='no') {
|
||||
form.DHCP6_KEEPRESOLV.disabled = false;
|
||||
var protocol = $(form).find('select[name="PROTOCOL:0"]').val() || 'ipv4';
|
||||
if (protocol != 'ipv4') $(form).find('input[name^="DNS6_SERVER"]').val('_(Obtaining DNSv6 server)_...');
|
||||
}
|
||||
setTimeout(refresh,25000);
|
||||
return true;
|
||||
}
|
||||
function selectProtocol(form,port,index) {
|
||||
if (index == null) {
|
||||
$(form).find('select[name^="PROTOCOL:"]').each(function() {
|
||||
var protocol = $(this).val() || 'ipv4';
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
var net4 = $('.'+'ipv4-'+port+'-'+i);
|
||||
var net6 = $('.'+'ipv6-'+port+'-'+i);
|
||||
var more4 = $('.'+'more-ipv4-'+port+'-'+i);
|
||||
var more6 = $('.'+'more-ipv6-'+port+'-'+i);
|
||||
switch (protocol) {
|
||||
case 'ipv4': net4.show(); net6.hide(); break;
|
||||
case 'ipv6': net4.hide(); net6.show(); break;
|
||||
case 'ipv4+ipv6': net4.show(); net6.show(); break;
|
||||
}
|
||||
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);
|
||||
});
|
||||
} else {
|
||||
var protocol = $(form).find('select[name="PROTOCOL:'+index+'"]').val() || 'ipv4';
|
||||
var net4 = $('.'+'ipv4-'+port+'-'+index);
|
||||
var net6 = $('.'+'ipv6-'+port+'-'+index);
|
||||
var more4 = $('.'+'more-ipv4-'+port+'-'+index);
|
||||
var more6 = $('.'+'more-ipv6-'+port+'-'+index);
|
||||
switch (protocol) {
|
||||
case 'ipv4': net4.show(); net6.hide(); break;
|
||||
case 'ipv6': net4.hide(); net6.show(); break;
|
||||
case 'ipv4+ipv6': net4.show(); net6.show(); break;
|
||||
}
|
||||
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) {
|
||||
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';
|
||||
if (protocol != 'ipv6') {
|
||||
$(form).find('input[name="IPADDR:'+index+'"]').prop('disabled',disabled4).prop('required',!disabled4);
|
||||
$(form).find('select[name="NETMASK:'+index+'"]').prop('disabled',disabled4);
|
||||
$(form).find('input[name="GATEWAY:'+index+'"]').prop('disabled',disabled4);
|
||||
}
|
||||
if (protocol != 'ipv4') {
|
||||
$(form).find('input[name="IPADDR6:'+index+'"]').prop('disabled',disabled6).prop('required',!disabled6);
|
||||
$(form).find('input[name="NETMASK6:'+index+'"]').prop('disabled',disabled6).prop('required',!disabled6);
|
||||
$(form).find('input[name="GATEWAY6:'+index+'"]').prop('disabled',disabled6);
|
||||
var privacy = $(form).find('select[name="PRIVACY6:'+index+'"]');
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
function checkDNSSettings(form) {
|
||||
var disabled = form.DHCP_KEEPRESOLV.value=='no';
|
||||
var protocol = $(form).find('select[name="PROTOCOL:0"]').val() || 'ipv4';
|
||||
if (protocol != 'ipv6') {
|
||||
form.DNS_SERVER1.disabled = disabled;
|
||||
form.DNS_SERVER1.required = !disabled;
|
||||
form.DNS_SERVER2.disabled = disabled;
|
||||
form.DNS_SERVER3.disabled = disabled;
|
||||
if (!form.DNS_SERVER2.value && disabled) $('#dnsserver2').hide(); else $('#dnsserver2').show();
|
||||
if (!form.DNS_SERVER3.value && disabled) $('#dnsserver3').hide(); else $('#dnsserver3').show();
|
||||
}
|
||||
}
|
||||
function checkDNSSettings6(form) {
|
||||
var disabled = form.DHCP6_KEEPRESOLV.value=='no';
|
||||
var protocol = $(form).find('select[name="PROTOCOL:0"]').val() || 'ipv4';
|
||||
if (protocol != 'ipv4') {
|
||||
form.DNS6_SERVER1.disabled = disabled;
|
||||
form.DNS6_SERVER2.disabled = disabled;
|
||||
form.DNS6_SERVER3.disabled = disabled;
|
||||
$('#dns6server1').show();
|
||||
if (!form.DNS6_SERVER2.value && disabled) $('#dns6server2').hide(); else $('#dns6server2').show();
|
||||
if (!form.DNS6_SERVER3.value && disabled) $('#dns6server3').hide(); else $('#dns6server3').show();
|
||||
}
|
||||
}
|
||||
function checkBondingSettings(form,ctrl,port) {
|
||||
var disabled = form.BONDING.value=='no';
|
||||
var mode = form.BONDING_MODE.value;
|
||||
if (ctrl>=0) {
|
||||
var me = ctrl==0 ? null : 'slow';
|
||||
if (disabled) {
|
||||
$('#bond-members-'+port).hide(me);
|
||||
} else {
|
||||
$('#bond-members-'+port).show(me);
|
||||
$('#bond-'+port).dropdownchecklist('destroy').dropdownchecklist({emptyText:'None', width:<?=$width[0]?>});
|
||||
}
|
||||
if (ctrl==1) checkBridgingSettings(form,1,port);
|
||||
}
|
||||
if (mode==1 || mode>4 || disabled) {$('#attention0').hide();} else {$('#attention0').show();}
|
||||
}
|
||||
function checkBridgingSettings(form,ctrl,port) {
|
||||
var me = ctrl==0 ? null : 'slow';
|
||||
var i = 0;
|
||||
if (form.BRIDGING.value=='yes' && form.BONDING.value=='no') {
|
||||
$('#bridge-members-'+port).show(me);
|
||||
$('#bridge-'+port).dropdownchecklist('destroy').dropdownchecklist({emptyText:'None', width:<?=$width[0]?>});
|
||||
} else {
|
||||
$('#bridge-members-'+port).hide(me);
|
||||
}
|
||||
}
|
||||
function checkNetworkAccess(form,port) {
|
||||
if (form.TYPE.value=='access') {
|
||||
$('.access-'+port).hide();
|
||||
$(form).find('input[name^="VLANID:"]').prop('required',false);
|
||||
} else {
|
||||
$('.access-'+port).show();
|
||||
$(form).find('input[name^="VLANID:"]').prop('required',true);
|
||||
}
|
||||
}
|
||||
function addVLAN(port) {
|
||||
var index = 1;
|
||||
while ($('#index-'+port+'-'+index).length) index++;
|
||||
var template = $($('<div/>').loadTemplate($('#network-template-'+port)).html().replace(/INDEX/g,index));
|
||||
var element = $('[id^="index-'+port+'-"]').last();
|
||||
$(element).after(template);
|
||||
$('form[name="'+$(element).parent().attr('name')+'"]').find('select').first().trigger('change');
|
||||
}
|
||||
function removeVLAN(element) {
|
||||
var id = $(element).attr('id').split('-');
|
||||
$(element).remove();
|
||||
$('#view-'+id[1]).find('select').first().trigger('change');
|
||||
}
|
||||
function disableForm(form) {
|
||||
$(form).find('input,select').not('input[value="_(Done)_"]').prop('disabled',true);
|
||||
$(form).find('input[name^="DESCRIPTION"],input[name^="#"]').prop('disabled',false);
|
||||
}
|
||||
var stopEvent = false;
|
||||
function noRun(form) {
|
||||
var arg1 = $(form).find('input[name="#arg[1]"]');
|
||||
if (arg1.val()=='') arg1.val('none');
|
||||
stopEvent = true;
|
||||
}
|
||||
function doRun(form) {
|
||||
if (stopEvent) {stopEvent = false; return;}
|
||||
var arg1 = $(form).find('input[name="#arg[1]"]');
|
||||
arg1.val($(form).find('input[name="#section"]').val());
|
||||
}
|
||||
function portcheck_eth0() {
|
||||
$.post('/webGui/include/CheckPort.php',{port:'eth0'},function(text) {
|
||||
var html = $('#user-notice').html();
|
||||
if (!html || html.indexOf('eth0')>0) showNotice(text);
|
||||
setTimeout(portcheck_eth0,10000);
|
||||
});
|
||||
}
|
||||
function portToggle(port,cmd) {
|
||||
$.post('/webGui/include/PortToggle.php',{port:port,cmd:cmd},function(){refresh();});
|
||||
}
|
||||
function viewToggle(eth,vlan) {
|
||||
var tag = vlan ? '#tag-'+eth+'-'+vlan : '#tag-'+eth;
|
||||
var view = vlan ? '#view-'+eth+'-'+vlan : '#view-'+eth;
|
||||
if ($(view).is(':visible')) {
|
||||
$(tag).removeClass('fa-chevron-up').addClass('fa-chevron-down');
|
||||
$.cookie(view,'hide',{expires:3650});
|
||||
} else {
|
||||
$(tag).removeClass('fa-chevron-down').addClass('fa-chevron-up');
|
||||
$.removeCookie(view);
|
||||
}
|
||||
$(view).toggle('slow');
|
||||
}
|
||||
var watchDHCP = new NchanSubscriber('/sub/dhcp',{subscriber:'websocket'});
|
||||
watchDHCP.on('message', function(data) {
|
||||
data = data.split(' ');
|
||||
for (var i=0,row; row=data[i]; i++) {
|
||||
var id = row.split('_');
|
||||
var form = $('form[name="'+id[0]+'_settings"]');
|
||||
var key = id[2].split('=');
|
||||
switch (id[1]) {
|
||||
case 'I': form.find('input[name="'+key[0].replace('-','_')+'"]').val(key[1]); break;
|
||||
case 'S': form.find('select[name="'+key[0].replace('-','_')+'"]').val(key[1]); break;
|
||||
}
|
||||
}
|
||||
});
|
||||
$(function() {
|
||||
var ctrl = "<span id='wait_eth0' class='status vshift red-text' style='display:none;font-size:1.2rem;font-style:italic'><i class='fa fa-spinner fa-spin'></i> _(Please wait)_... _(configuring interface)_</span>";
|
||||
var form = document.eth0_settings;
|
||||
<?if ($tabbed && !$service):?>
|
||||
$('#tab1').bind({click:function(){
|
||||
$('#bond-eth0').dropdownchecklist('destroy').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[0]?>});
|
||||
$('#bridge-eth0').dropdownchecklist('destroy').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[0]?>});
|
||||
}});
|
||||
<?endif;?>
|
||||
if (!$.cookie('#view-eth0')) {$('#view-eth0').show(); $('#tag-eth0').removeClass('fa-chevron-down').addClass('fa-chevron-up');}
|
||||
<?foreach ($vlan_eth0 as $i):?>
|
||||
if (!$.cookie('#view-eth0-<?=$i?>')) {$('#view-eth0-<?=$i?>').show(); $('#tag-eth0-<?=$i?>').removeClass('fa-chevron-down').addClass('fa-chevron-up');}
|
||||
<?endforeach;?>
|
||||
$('#bond-eth0').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[0]?>});
|
||||
$('#bridge-eth0').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[0]?>});
|
||||
checkBondingSettings(form,0,'eth0');
|
||||
checkBridgingSettings(form,0,'eth0');
|
||||
checkNetworkAccess(form,'eth0');
|
||||
selectProtocol(form,'eth0');
|
||||
<?if ($service):?>
|
||||
disableForm(form);
|
||||
$('#bond-eth0').dropdownchecklist('disable');
|
||||
$('#bridge-eth0').dropdownchecklist('disable');
|
||||
var protocol = $(form).find('select[name="PROTOCOL:0"]').val() || 'ipv4';
|
||||
if (form.DNS_SERVER2.value) $('#dnsserver2').show(); else $('#dnsserver2').hide();
|
||||
if (form.DNS_SERVER3.value) $('#dnsserver3').show(); else $('#dnsserver3').hide();
|
||||
if (form.DNS6_SERVER1.value) $('#dns6server1').show(); else $('#dns6server1').hide();
|
||||
if (form.DNS6_SERVER2.value) $('#dns6server2').show(); else $('#dns6server2').hide();
|
||||
if (form.DNS6_SERVER3.value) $('#dns6server3').show(); else $('#dns6server3').hide();
|
||||
<?else:?>
|
||||
checkDNSSettings(form);
|
||||
checkDNSSettings6(form);
|
||||
<?endif;?>
|
||||
<?if ($tabbed):?>
|
||||
$('.tabs').append(ctrl.replace('vshift',''));
|
||||
<?else:?>
|
||||
$('div.title').eq(0).find('span.left').append(ctrl);
|
||||
<?endif;?>
|
||||
portcheck_eth0();
|
||||
watchDHCP.start();
|
||||
});
|
||||
</script>
|
||||
<form markdown="1" name="eth0_settings" method="POST" action="/update.php" target="progressFrame" onchange="doRun(this)" onsubmit="return prepareSettings(this)">
|
||||
<input type="hidden" name="#file" value="<?=$ini?>">
|
||||
<input type="hidden" name="#include" value="/webGui/include/update.ethernet.php">
|
||||
<input type="hidden" name="#section" value="eth0">
|
||||
<input type="hidden" name="#command" value="/webGui/scripts/netconfig">
|
||||
<input type="hidden" name="#arg[1]" value="">
|
||||
<input type="hidden" name="BONDNAME" value="bond0">
|
||||
<input type="hidden" name="BONDING_MIIMON" value="100">
|
||||
<input type="hidden" name="BRNAME" value="br0">
|
||||
<input type="hidden" name="BRSTP" value="no">
|
||||
<input type="hidden" name="BRFD" value="0">
|
||||
_(Interface description)_:
|
||||
: <span class="status vshift"><i id="tag-eth0" class="fa fa-fw fa-chevron-down" style="cursor:pointer" onclick="viewToggle('eth0')"></i></span>
|
||||
<input type="text" name="DESCRIPTION:0" maxlength="80" value="<?=htmlspecialchars(_var($eth0,"DESCRIPTION:0"))?>" oninput="noRun(this.form)">
|
||||
|
||||
:eth_interface_description_help:
|
||||
|
||||
<div markdown="1" id="view-eth0" style="display:none">
|
||||
_(MAC address)_:
|
||||
: <?=strtoupper(exec("ip link show eth0|grep -Pom1 'ether \K\S+'"))?>
|
||||
|
||||
:eth_mac_address_help:
|
||||
|
||||
_(Enable bonding)_:
|
||||
: <select name="BONDING" onchange="checkBondingSettings(this.form,1,'eth0')">
|
||||
<?=mk_option(_var($eth0,'BONDING'), "no", _("No"))?>
|
||||
<?=mk_option(_var($eth0,'BONDING'), "yes", _("Yes"))?>
|
||||
</select>
|
||||
|
||||
:eth_enable_bonding_help:
|
||||
|
||||
<div markdown="1" id="bond-members-eth0" style="display:none">
|
||||
_(Bonding mode)_:
|
||||
: <select name="BONDING_MODE" onchange="checkBondingSettings(this.form,-1,'eth0')">
|
||||
<?=mk_option(_var($eth0,'BONDING_MODE'), "0", _("balance-rr")." (0)")?>
|
||||
<?=mk_option(_var($eth0,'BONDING_MODE'), "1", _("active-backup")." (1)",isset($eth0['BONDING_MODE'])?'':'selected')?>
|
||||
<?=mk_option(_var($eth0,'BONDING_MODE'), "2", _("balance-xor")." (2)")?>
|
||||
<?=mk_option(_var($eth0,'BONDING_MODE'), "3", _("broadcast")." (3)")?>
|
||||
<?=mk_option(_var($eth0,'BONDING_MODE'), "4", _("802.3ad")." (4)")?>
|
||||
<?=mk_option(_var($eth0,'BONDING_MODE'), "5", _("balance-tlb")." (5)")?>
|
||||
<?=mk_option(_var($eth0,'BONDING_MODE'), "6", _("balance-alb")." (6)")?>
|
||||
</select>
|
||||
<span id="attention0" style="display:none">**_(Attention)_:** _(this mode requires a network switch with proper setup and support)_...</span>
|
||||
|
||||
:eth_bonding_mode_help:
|
||||
|
||||
_(Bonding members of)_ bond0:
|
||||
: <select id="bond-eth0" name="BONDNICS" multiple="multiple" style="display:none">
|
||||
<?=mk_option(_var($eth0,'BONDNICS'),'eth0','eth0','selected disabled')?>
|
||||
<?foreach ($ports as $port):?>
|
||||
<?if (!locked('eth0',$port)) echo mk_option_check(_var($eth0,'BONDNICS'),$port,$port)?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
:eth_bonding_members_help:
|
||||
|
||||
</div>
|
||||
_(Enable bridging)_:
|
||||
: <select name="BRIDGING" onchange="checkBridgingSettings(this.form,1,'eth0')">
|
||||
<?=mk_option(_var($eth0,'BRIDGING'), "no", _("No"))?>
|
||||
<?=mk_option(_var($eth0,'BRIDGING'), "yes", _("Yes"))?>
|
||||
</select>
|
||||
|
||||
:eth_enable_bridging_help:
|
||||
|
||||
<div markdown="1" id="bridge-members-eth0" style="display:none">
|
||||
_(Bridging members of)_ br0:
|
||||
: <select id="bridge-eth0" name="BRNICS" multiple="multiple" style="display:none">
|
||||
<?=mk_option(_var($eth0,'BRNICS'),'eth0','eth0','selected disabled')?>
|
||||
<?foreach ($ports as $port):?>
|
||||
<?if (!locked('eth0',$port)) echo mk_option_check(_var($eth0,'BRNICS'),$port,$port)?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
:eth_bridging_members_help:
|
||||
|
||||
</div>
|
||||
_(Network protocol)_:
|
||||
: <select name="PROTOCOL:0" onchange="selectProtocol(this.form,'eth0',0)">
|
||||
<?=mk_option(_var($eth0,"PROTOCOL:0"), 'ipv4', _('IPv4 only'))?>
|
||||
<?=mk_option(_var($eth0,"PROTOCOL:0"), 'ipv6', _('IPv6 only'))?>
|
||||
<?=mk_option(_var($eth0,"PROTOCOL:0"), 'ipv4+ipv6', _('IPv4 + IPv6'))?>
|
||||
</select>
|
||||
|
||||
:eth_network_protocol_help:
|
||||
|
||||
<div markdown="1" class="ipv4-eth0-0" style="display:none">
|
||||
_(IPv4 address assignment)_:
|
||||
: <select name="USE_DHCP:0" onchange="selectProtocol(this.form,'eth0',0)">
|
||||
<?=mk_option(_var($eth0,"USE_DHCP:0"), 'yes', _('Automatic'))?>
|
||||
<?=mk_option(_var($eth0,"USE_DHCP:0"), 'no', _('Static'))?>
|
||||
</select>
|
||||
|
||||
:eth_ipv4_address_assignment_help:
|
||||
|
||||
<div markdown="1" class="more-ipv4-eth0-0" style="display:none">
|
||||
_(IPv4 address)_:
|
||||
: <input type="text" name="IPADDR:0" maxlength="15" value="<?=_var($eth0,"IPADDR:0")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">/<select name="NETMASK:0" class="slim">
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.0.0.0", "8")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.0.0", "16")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.128.0", "17")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.192.0", "18")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.224.0", "19")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.240.0", "20")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.248.0", "21")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.252.0", "22")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.254.0", "23")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.255.0", "24", $eth0["IPADDR:0"]?"":"selected")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.255.128", "25")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.255.192", "26")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.255.224", "27")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.255.240", "28")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.255.248", "29")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:0"), "255.255.255.252", "30")?>
|
||||
</select>
|
||||
|
||||
:eth_ipv4_address_help:
|
||||
|
||||
_(IPv4 default gateway)_:
|
||||
: <input type="text" name="GATEWAY:0" maxlength="15" value="<?=_var($eth0,"GATEWAY:0")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
<input type="text" name="METRIC:0" min="0" max="9999" value="<?=_var($eth0,"METRIC:0")?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *_(optional metric (lowest is preferred, 0 is no default gateway))_*
|
||||
|
||||
:eth_ipv4_default_gateway_help:
|
||||
|
||||
</div>
|
||||
_(IPv4 DNS server assignment)_:
|
||||
: <select name="DHCP_KEEPRESOLV" onchange="checkDNSSettings(this.form)">
|
||||
<?=mk_option(_var($eth0,'DHCP_KEEPRESOLV'), "no", _("Automatic"))?>
|
||||
<?=mk_option(_var($eth0,'DHCP_KEEPRESOLV'), "yes", _("Static"))?>
|
||||
</select>
|
||||
|
||||
:eth_ipv4_dns_server_assignment_help:
|
||||
|
||||
_(IPv4 DNS server)_:
|
||||
: <input type="text" name="DNS_SERVER1" maxlength="15" value="<?=_var($eth0,'DNS_SERVER1')?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
|
||||
:eth_ipv4_dns_server_help:
|
||||
|
||||
<div markdown="1" id="dnsserver2" style="display:none">
|
||||
_(IPv4 DNS server)_ 2:
|
||||
: <input type="text" name="DNS_SERVER2" maxlength="15" value="<?=_var($eth0,'DNS_SERVER2')?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
|
||||
:eth_ipv4_dns_server2_help:
|
||||
|
||||
</div>
|
||||
<div markdown="1" id="dnsserver3" style="display:none">
|
||||
_(IPv4 DNS server)_ 3:
|
||||
: <input type="text" name="DNS_SERVER3" maxlength="15" value="<?=_var($eth0,'DNS_SERVER3')?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
|
||||
:eth_ipv4_dns_server3_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div markdown="1" class="ipv6-eth0-0" style="display:none">
|
||||
_(IPv6 address assignment)_:
|
||||
: <select name="USE_DHCP6:0" onchange="selectProtocol(this.form,'eth0',0)">
|
||||
<?=mk_option(_var($eth0,"USE_DHCP6:0"), 'yes', _('Automatic'))?>
|
||||
<?=mk_option(_var($eth0,"USE_DHCP6:0"), 'no', _('Static'))?>
|
||||
</select>
|
||||
|
||||
:eth_ipv6_address_assignment_help:
|
||||
|
||||
<div markdown="1" class="more-ipv6-eth0-0" style="display:none">
|
||||
_(IPv6 address)_:
|
||||
: <input type="text" name="IPADDR6:0" maxlength="39" value="<?=_var($eth0,"IPADDR6:0")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">/<input type="number" name="NETMASK6:0" min="1" max="128" value="<?=_var($eth0,"NETMASK6:0")?>" class="slim">
|
||||
|
||||
:eth_ipv6_address_help:
|
||||
|
||||
_(IPv6 default gateway)_:
|
||||
: <input type="text" name="GATEWAY6:0" maxlength="39" value="<?=_var($eth0,"GATEWAY6:0")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
<input type="text" name="METRIC6:0" min="0" max="9999" value="<?=_var($eth0,"METRIC6:0")?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *_(optional metric (lowest is preferred, 0 is no default gateway))_*
|
||||
|
||||
:eth_ipv6_default_gateway_help:
|
||||
|
||||
_(IPv6 privacy extensions)_:
|
||||
: <select name="PRIVACY6:0">
|
||||
<?=mk_option(_var($eth0,"PRIVACY6:0"), "0", _("Disabled"))?>
|
||||
<?=mk_option(_var($eth0,"PRIVACY6:0"), "2", _("Enabled"))?>
|
||||
</select>
|
||||
|
||||
:eth_ipv6_privacy_extensions_help:
|
||||
|
||||
</div>
|
||||
<div markdown="1" id="dns6server1" style="display:none">
|
||||
_(IPv6 DNS server assignment)_:
|
||||
: <select name="DHCP6_KEEPRESOLV" onchange="checkDNSSettings6(this.form)">
|
||||
<?=mk_option(_var($eth0,'DHCP6_KEEPRESOLV'), "no", _("Automatic"))?>
|
||||
<?=mk_option(_var($eth0,'DHCP6_KEEPRESOLV'), "yes", _("Static"))?>
|
||||
</select>
|
||||
|
||||
:eth_ipv6_dns_server_assignment_help:
|
||||
|
||||
_(IPv6 DNS server)_:
|
||||
: <input type="text" name="DNS6_SERVER1" maxlength="39" value="<?=_var($eth0,'DNS6_SERVER1')?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
|
||||
:eth_ipv6_dns_server_help:
|
||||
|
||||
</div>
|
||||
<div markdown="1" id="dns6server2" style="display:none">
|
||||
_(IPv6 DNS server)_ 2:
|
||||
: <input type="text" name="DNS6_SERVER2" maxlength="39" value="<?=_var($eth0,'DNS6_SERVER2')?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
|
||||
:eth_ipv6_dns_server2_help:
|
||||
|
||||
</div>
|
||||
<div markdown="1" id="dns6server3" style="display:none">
|
||||
_(IPv6 DNS server)_ 3:
|
||||
: <input type="text" name="DNS6_SERVER3" maxlength="39" value="<?=_var($eth0,'DNS6_SERVER3')?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
|
||||
:eth_ipv6_dns_server3_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
_(Desired MTU)_:
|
||||
: <input type="number" name="MTU" min="68" max="9198" value="<?=_var($eth0,'MTU')?>" class="narrow" placeholder="1500">
|
||||
|
||||
:eth_desired_mtu_help:
|
||||
|
||||
_(Enable VLANs)_:
|
||||
: <select name="TYPE" onchange="checkNetworkAccess(this.form,'eth0')">
|
||||
<?=mk_option(_var($eth0,'TYPE'), 'access', _('No'))?>
|
||||
<?=mk_option(_var($eth0,'TYPE'), 'trunk', _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:eth_enable_vlans_help:
|
||||
|
||||
</div>
|
||||
<div id='index-eth0-0'></div>
|
||||
<?foreach ($vlan_eth0 as $i):?>
|
||||
<div markdown="1" id="index-eth0-<?=$i?>" class="access-eth0 shade-<?=$display['theme']?>" style="display:none">
|
||||
_(Interface description)_:
|
||||
: <span class="status vshift"><i id="tag-eth0-<?=$i?>" class="fa fa-fw fa-chevron-down" style="cursor:pointer" onclick="viewToggle('eth0','<?=$i?>')"></i></span>
|
||||
<input type="text" name="DESCRIPTION:<?=$i?>" maxlength="80" value="<?=htmlspecialchars(_var($eth0,"DESCRIPTION:$i"))?>" oninput="noRun(this.form)">
|
||||
|
||||
:eth_interface_description_help:
|
||||
|
||||
<div markdown="1" id="view-eth0-<?=$i?>" style="display:none">
|
||||
_(VLAN number)_:
|
||||
: <input type="number" name="VLANID:<?=$i?>" min="1" max="4095" value="<?=_var($eth0,"VLANID:$i")?>" class="narrow gap" required>
|
||||
<?if (!$service):?><input type="button" class="form" value="_(Delete VLAN)_" onclick="removeVLAN($('#index-eth0-<?=$i?>'))"><?endif;?>
|
||||
|
||||
:eth_vlan_number_help:
|
||||
|
||||
_(Network protocol)_:
|
||||
: <select name="PROTOCOL:<?=$i?>" onchange="selectProtocol(this.form,'eth0',<?=$i?>)">
|
||||
<?=mk_option(_var($eth0,"PROTOCOL:$i"), 'ipv4', _('IPv4 only'))?>
|
||||
<?=mk_option(_var($eth0,"PROTOCOL:$i"), 'ipv6', _('IPv6 only'))?>
|
||||
<?=mk_option(_var($eth0,"PROTOCOL:$i"), 'ipv4+ipv6', _('IPv4 + IPv6'))?>
|
||||
</select>
|
||||
|
||||
:eth_network_protocol_help:
|
||||
|
||||
<div markdown="1" class="ipv4-eth0-<?=$i?>" style="display:none">
|
||||
_(IPv4 address assignment)_:
|
||||
: <select name="USE_DHCP:<?=$i?>" onchange="selectProtocol(this.form,'eth0',<?=$i?>)">
|
||||
<?=mk_option(_var($eth0,"USE_DHCP:$i"), 'yes', _('Automatic'))?>
|
||||
<?=mk_option(_var($eth0,"USE_DHCP:$i"), 'no', _('Static'))?>
|
||||
<?if ($i>0):?>
|
||||
<?=mk_option(_var($eth0,"USE_DHCP:$i"), '', _('None'))?>
|
||||
<?endif;?>
|
||||
</select>
|
||||
|
||||
:eth_ipv4_address_assignment_help:
|
||||
|
||||
<div markdown="1" class="more-ipv4-eth0-<?=$i?>" style="display:none">
|
||||
_(IPv4 address)_:
|
||||
: <input type="text" name="IPADDR:<?=$i?>" maxlength="15" value="<?=_var($eth0,"IPADDR:$i")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">/<select name="NETMASK:<?=$i?>" class="slim">
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.0.0.0", "8")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.0.0", "16")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.128.0", "17")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.192.0", "18")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.224.0", "19")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.240.0", "20")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.248.0", "21")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.252.0", "22")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.254.0", "23")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.255.0", "24", _var($eth0,"IPADDR:$i")?"":"selected")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.255.128", "25")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.255.192", "26")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.255.224", "27")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.255.240", "28")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.255.248", "29")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:$i"), "255.255.255.252", "30")?>
|
||||
</select>
|
||||
|
||||
:eth_ipv4_address_help:
|
||||
|
||||
_(IPv4 default gateway)_:
|
||||
: <input type="text" name="GATEWAY:<?=$i?>" maxlength="15" value="<?=_var($eth0,"GATEWAY:$i")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
<input type="text" name="METRIC:<?=$i?>" min="0" max="9999" value="<?=_var($eth0,"METRIC:$i")?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *_(optional metric (lowest is preferred, 0 is no default gateway))_*
|
||||
|
||||
:eth_ipv4_default_gateway_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div markdown="1" class="ipv6-eth0-<?=$i?>" style="display:none">
|
||||
_(IPv6 address assignment)_:
|
||||
: <select name="USE_DHCP6:<?=$i?>" onchange="selectProtocol(this.form,'eth0',<?=$i?>)">
|
||||
<?=mk_option(_var($eth0,"USE_DHCP6:$i"), 'yes', _('Automatic'))?>
|
||||
<?=mk_option(_var($eth0,"USE_DHCP6:$i"), 'no', _('Static'))?>
|
||||
<?if ($i>0):?>
|
||||
<?=mk_option(_var($eth0,"USE_DHCP6:$i"), '', _('None'))?>
|
||||
<?endif;?>
|
||||
</select>
|
||||
|
||||
:eth_ipv6_address_assignment_help:
|
||||
|
||||
<div markdown="1" class="more-ipv6-eth0-<?=$i?>" style="display:none">
|
||||
_(IPv6 address)_:
|
||||
: <input type="text" name="IPADDR6:<?=$i?>" maxlength="39" value="<?=_var($eth0,"IPADDR6:$i")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">/<input type="number" name="NETMASK6:<?=$i?>" min="1" max="128" value="<?=_var($eth0,"NETMASK6:$i")?>" class="slim">
|
||||
|
||||
:eth_ipv6_address_help:
|
||||
|
||||
_(IPv6 default gateway)_:
|
||||
: <input type="text" name="GATEWAY6:<?=$i?>" maxlength="39" value="<?=_var($eth0,"GATEWAY6:$i")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
<input type="text" name="METRIC6:<?=$i?>" min="0" max="9999" value="<?=_var($eth0,"METRIC6:$i")?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *_(optional metric (lowest is preferred, 0 is no default gateway))_*
|
||||
|
||||
:eth_ipv6_default_gateway_help:
|
||||
|
||||
_(IPv6 privacy extensions)_:
|
||||
: <select name="PRIVACY6:<?=$i?>">
|
||||
<?=mk_option(_var($eth0,"PRIVACY6:$i"), "0", _("Disabled"))?>
|
||||
<?=mk_option(_var($eth0,"PRIVACY6:$i"), "2", _("Enabled"))?>
|
||||
</select>
|
||||
|
||||
:eth_ipv6_privacy_extensions_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?endforeach;?>
|
||||
|
||||
|
||||
: <input type="submit" value="_(Apply)_" onclick="$('#wait_eth0').show()" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
<?if (!$service):?>
|
||||
<input type="button" class="access-eth0" value="_(Add VLAN)_" onclick="addVLAN('eth0')" style="display:none">
|
||||
<?else:?><?=sprintf(_('Stop **%s** to make changes, see'),$service).' (<a href="/Settings">'._('Settings').'</a>)'?><?endif;?>
|
||||
</form>
|
||||
|
||||
<script markdown="1" type="text/html" id="network-template-eth0">
|
||||
<div markdown="1" id="index-eth0-INDEX" class="access-eth0 shade-<?=$display['theme']?>">
|
||||
_(Interface description)_:
|
||||
: <span class="status vshift"><i id="tag-eth0-INDEX" class="fa fa-fw fa-chevron-up" style="cursor:pointer" onclick="viewToggle('eth0','INDEX')"></i></span>
|
||||
<input type="text" name="DESCRIPTION:INDEX" maxlength="80" value="<?=htmlspecialchars(_var($eth0,"DESCRIPTION:INDEX"))?>" oninput="noRun(this.form)">
|
||||
|
||||
<div markdown="1" id="view-eth0-INDEX">
|
||||
_(VLAN number)_:
|
||||
: <input type="number" name="VLANID:INDEX" min="1" max="4095" value="<?=_var($eth0,"VLANID:INDEX")?>" class="narrow gap" required>
|
||||
<input type="button" class="form" value="_(Delete VLAN)_" onclick="removeVLAN($('#index-eth0-INDEX'))">
|
||||
|
||||
_(Network protocol)_:
|
||||
: <select name="PROTOCOL:INDEX" onchange="selectProtocol(this.form,'eth0',INDEX)">
|
||||
<?=mk_option(_var($eth0,"PROTOCOL:INDEX"), 'ipv4', _('IPv4 only'))?>
|
||||
<?=mk_option(_var($eth0,"PROTOCOL:INDEX"), 'ipv6', _('IPv6 only'))?>
|
||||
<?=mk_option(_var($eth0,"PROTOCOL:INDEX"), 'ipv4+ipv6', _('IPv4 + IPv6'))?>
|
||||
</select>
|
||||
|
||||
<div markdown="1" class="ipv4-eth0-INDEX" style="display:none">
|
||||
_(IPv4 address assignment)_:
|
||||
: <select name="USE_DHCP:INDEX" onchange="selectProtocol(this.form,'eth0',INDEX)">
|
||||
<?=mk_option(_var($eth0,"USE_DHCP:INDEX"), 'yes', _('Automatic'))?>
|
||||
<?=mk_option(_var($eth0,"USE_DHCP:INDEX"), 'no', _('Static'))?>
|
||||
<?=mk_option(_var($eth0,"USE_DHCP:INDEX"), '', _('None'))?>
|
||||
</select>
|
||||
|
||||
<div markdown="1" class="more-ipv4-eth0-INDEX" style="display:none">
|
||||
_(IPv4 address)_:
|
||||
: <input type="text" name="IPADDR:INDEX" maxlength="15" value="<?=_var($eth0,"IPADDR:INDEX")?>" class="narrow" pattern="<?=$validIP4?>" title="=_(IPv4 address A.B.C.D)_">/<select name="NETMASK:INDEX" class="slim">
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.0.0.0", "8")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.0.0", "16")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.128.0", "17")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.192.0", "18")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.224.0", "19")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.240.0", "20")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.248.0", "21")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.252.0", "22")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.254.0", "23")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.255.0", "24", "selected")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.255.128", "25")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.255.192", "26")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.255.224", "27")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.255.240", "28")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.255.248", "29")?>
|
||||
<?=mk_option(_var($eth0,"NETMASK:INDEX"), "255.255.255.252", "30")?>
|
||||
</select>
|
||||
|
||||
_(IPv4 default gateway)_:
|
||||
: <input type="text" name="GATEWAY:INDEX" maxlength="15" value="<?=_var($eth0,"GATEWAY:INDEX")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
<input type="text" name="METRIC:INDEX" min="1" max="9999" value="<?=_var($eth0,"METRIC:INDEX")?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *_(optional metric (lowest is preferred, 0 is no default gateway))_*
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div markdown="1" class="ipv6-eth0-INDEX" style="display:none">
|
||||
_(IPv6 address assignment)_:
|
||||
: <select name="USE_DHCP6:INDEX" onchange="selectProtocol(this.form,'eth0',INDEX)">
|
||||
<?=mk_option(_var($eth0,"USE_DHCP6:INDEX"), 'yes', _('Automatic'))?>
|
||||
<?=mk_option(_var($eth0,"USE_DHCP6:INDEX"), 'no', _('Static'))?>
|
||||
<?=mk_option(_var($eth0,"USE_DHCP6:INDEX"), '', _('None'))?>
|
||||
</select>
|
||||
|
||||
<div markdown="1" class="more-ipv6-eth0-INDEX" style="display:none">
|
||||
_(IPv6 address)_:
|
||||
: <input type="text" name="IPADDR6:INDEX" maxlength="39" value="<?=_var($eth0,"IPADDR6:INDEX")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">/<input type="number" name="NETMASK6:INDEX" min="1" max="128" value="<?=_var($eth0,"NETMASK6:INDEX")?>" class="slim">
|
||||
|
||||
_(IPv6 default gateway)_:
|
||||
: <input type="text" name="GATEWAY6:INDEX" maxlength="39" value="<?=_var($eth0,"GATEWAY6:INDEX")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
<input type="text" name="METRIC6:INDEX" min="1" max="9999" value="<?=_var($eth0,"METRIC6:INDEX")?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *_(optional metric (lowest is preferred, 0 is no default gateway))_*
|
||||
|
||||
_(IPv6 privacy extensions)_:
|
||||
: <select name="PRIVACY6:INDEX">
|
||||
<?=mk_option(_var($eth0,'PRIVACY6:INDEX'), "0", _("Disabled"))?>
|
||||
<?=mk_option(_var($eth0,'PRIVACY6:INDEX'), "2", _("Enabled"))?>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
@@ -0,0 +1,455 @@
|
||||
Menu="parentname:nnn"
|
||||
Title="_(Interface)_ ethX"
|
||||
Tag="icon-ethernet"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$locked = locked('ethX','ethX');
|
||||
|
||||
// get VLAN interfaces
|
||||
$vlan_ethX = $sort_ethX = [];
|
||||
if (!$locked && isset($ethX)) foreach (vlanID($ethX) as $key => $val) {$vlan_ethX[] = index($key); $sort_ethX[] = (int)$val;}
|
||||
array_multisort($sort_ethX,$vlan_ethX);
|
||||
|
||||
$cmd = 'Down';
|
||||
$more = true;
|
||||
if (strpos($locked,'bond')===0 || strpos($locked,'br')===0) {
|
||||
[$master_ethX,$root] = my_explode(' ',$locked);
|
||||
$reason = _('member of')." $master_ethX ("._('see interface')." $root)";
|
||||
$class = 'green-text';
|
||||
} elseif (!exec("ip link show ethX|grep -om1 'UP>'")) {
|
||||
$reason = _("shutdown")." ("._("inactive").")";
|
||||
$class = 'blue-text';
|
||||
$cmd = 'Up';
|
||||
} elseif (empty($ethX)) {
|
||||
$reason = _("not configured");
|
||||
$class = 'red-text';
|
||||
} else {
|
||||
$more = false;
|
||||
$class = '';
|
||||
}
|
||||
?>
|
||||
<script>
|
||||
function portcheck_ethX() {
|
||||
$.post('/webGui/include/CheckPort.php',{port:'ethX'},function(text) {
|
||||
var html = $('#user-notice').html();
|
||||
if (!html || html.indexOf('ethX')>0) showNotice(text);
|
||||
setTimeout(portcheck_ethX,10000);
|
||||
});
|
||||
}
|
||||
$(function() {
|
||||
var ctrl = "<span id='wait_ethX' class='status vshift red-text' style='display:none;font-size:1.2rem;font-style:italic'><i class='fa fa-spinner fa-spin'></i> _(Please wait)_... _(configuring interface)_</span>";
|
||||
var form = document.ethX_settings;
|
||||
<?if ($tabbed && !$service):?>
|
||||
$('#tabX').bind({click:function(){
|
||||
$('#bond-ethX').dropdownchecklist('destroy').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[0]?>});
|
||||
$('#bridge-ethX').dropdownchecklist('destroy').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[0]?>});
|
||||
}});
|
||||
<?endif;?>
|
||||
if (!$.cookie('#view-ethX')) {$('#view-ethX').show(); $('#tag-ethX').removeClass('fa-chevron-down').addClass('fa-chevron-up');}
|
||||
<?foreach ($vlan_ethX as $i):?>
|
||||
if (!$.cookie('#view-ethX-<?=$i?>')) {$('#view-ethX-<?=$i?>').show(); $('#tag-ethX-<?=$i?>').removeClass('fa-chevron-down').addClass('fa-chevron-up');}
|
||||
<?endforeach;?>
|
||||
$('#bond-ethX').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[0]?>});
|
||||
$('#bridge-ethX').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[0]?>});
|
||||
checkBondingSettings(form,0,'ethX');
|
||||
checkBridgingSettings(form,0,'ethX');
|
||||
checkNetworkAccess(form,'ethX');
|
||||
selectProtocol(form,'ethX');
|
||||
<?if (!$tabbed):?>
|
||||
$('div.title').each(function(){
|
||||
if ($(this).text().indexOf('Interface ethX')==0) $(this).find('span.left').append(ctrl);
|
||||
});
|
||||
<?endif;?>
|
||||
<?if (isset($master_ethX)):?>
|
||||
$('div.slave-ethX').hide();
|
||||
disableForm(form);
|
||||
<?elseif ($service):?>
|
||||
disableForm(form);
|
||||
<?endif;?>
|
||||
<?if ($no_eth0):?>
|
||||
$('input[name="#shut_ethX"]').prop('disabled',true);
|
||||
<?endif;?>
|
||||
setTimeout(portcheck_ethX,Number('ethX'.substr(3))*1000);
|
||||
});
|
||||
</script>
|
||||
<form markdown="1" name="ethX_settings" method="POST" action="/update.php" target="progressFrame" onchange="doRun(this)" onsubmit="return prepareSettings(this)">
|
||||
<input type="hidden" name="#file" value="<?=$ini?>">
|
||||
<input type="hidden" name="#include" value="/webGui/include/update.ethernet.php">
|
||||
<input type="hidden" name="#section" value="ethX">
|
||||
<input type="hidden" name="#command" value="/webGui/scripts/netconfig">
|
||||
<input type="hidden" name="#arg[1]" value="">
|
||||
<input type="hidden" name="BONDNAME" value="bondX">
|
||||
<input type="hidden" name="BONDING_MIIMON" value="100">
|
||||
<input type="hidden" name="BRNAME" value="brX">
|
||||
<input type="hidden" name="BRSTP" value="no">
|
||||
<input type="hidden" name="BRFD" value="0">
|
||||
_(Interface description)_:
|
||||
: <span class="status vshift"><i id="tag-ethX" class="fa fa-fw fa-chevron-down" style="cursor:pointer" onclick="viewToggle('ethX')"></i></span>
|
||||
<?if (!$more):?>
|
||||
<input type="text" name="DESCRIPTION:0" maxlength="80" value="<?=htmlspecialchars(_var($ethX,"DESCRIPTION:0"))?>" oninput="noRun(this.form)">
|
||||
<?else:?>
|
||||
<span class="<?=$class?>"><?=$reason?></span>
|
||||
<?endif;?>
|
||||
|
||||
:eth_interface_description_help:
|
||||
|
||||
<div markdown="1" id="view-ethX" style="display:none">
|
||||
_(MAC address)_:
|
||||
: <?=strtoupper(exec("ip link show ethX|grep -Pom1 'ether \K\S+'"))?>
|
||||
|
||||
:eth_mac_address_help:
|
||||
|
||||
<div markdown="1" class="slave-ethX">
|
||||
_(Enable bonding)_:
|
||||
: <select name="BONDING" onchange="checkBondingSettings(this.form,1,'ethX')">
|
||||
<?=mk_option(_var($ethX,'BONDING'), "no", _("No"))?>
|
||||
<?=mk_option(_var($ethX,'BONDING'), "yes", _("Yes"))?>
|
||||
</select>
|
||||
|
||||
:eth_enable_bonding_help:
|
||||
|
||||
<div markdown="1" id="bond-members-ethX" style="display:none">
|
||||
_(Bonding mode)_:
|
||||
: <select name="BONDING_MODE" onchange="checkBondingSettings(this.form,-1,'ethX')">
|
||||
<?=mk_option(_var($ethX,'BONDING_MODE'), "0", _("balance-rr")." (0)")?>
|
||||
<?=mk_option(_var($ethX,'BONDING_MODE'), "1", _("active-backup")." (1)",isset($ethX['BONDING_MODE'])?'':'selected')?>
|
||||
<?=mk_option(_var($ethX,'BONDING_MODE'), "2", _("balance-xor")." (2)")?>
|
||||
<?=mk_option(_var($ethX,'BONDING_MODE'), "3", _("broadcast")." (3)")?>
|
||||
<?=mk_option(_var($ethX,'BONDING_MODE'), "4", _("802.3ad")." (4)")?>
|
||||
<?=mk_option(_var($ethX,'BONDING_MODE'), "5", _("balance-tlb")." (5)")?>
|
||||
<?=mk_option(_var($ethX,'BONDING_MODE'), "6", _("balance-alb")." (6)")?>
|
||||
</select>
|
||||
<span id="attention0" style="display:none">**_(Attention)_:** _(this mode requires a network switch with proper setup and support)_...</span>
|
||||
|
||||
:eth_bonding_mode_help:
|
||||
|
||||
_(Bonding members of)_ bondX:
|
||||
: <select id="bond-ethX" name="BONDNICS" multiple="multiple" style="display:none">
|
||||
<?=mk_option(_var($ethX,'BONDNICS'),'ethX','ethX','selected disabled')?>
|
||||
<?foreach ($ports as $port):?>
|
||||
<?if ($port!='ethX' && !locked('ethX',$port)) echo mk_option_check(_var($ethX,'BONDNICS'),$port,$port)?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
:eth_bonding_members_help:
|
||||
|
||||
</div>
|
||||
_(Enable bridging)_:
|
||||
: <select name="BRIDGING" onchange="checkBridgingSettings(this.form,1,'ethX')">
|
||||
<?=mk_option(_var($ethX,'BRIDGING'), "no", _("No"))?>
|
||||
<?=mk_option(_var($ethX,'BRIDGING'), "yes", _("Yes"))?>
|
||||
</select>
|
||||
|
||||
:eth_enable_bridging_help:
|
||||
|
||||
<div markdown="1" id="bridge-members-ethX" style="display:none">
|
||||
_(Bridging members of)_ brX:
|
||||
: <select id="bridge-ethX" name="BRNICS" multiple="multiple" style="display:none">
|
||||
<?=mk_option(_var($ethX,'BRNICS'),'ethX','ethX','selected disabled')?>
|
||||
<?foreach ($ports as $port):?>
|
||||
<?if ($port!='ethX' && !locked('ethX',$port)) echo mk_option_check(_var($ethX,'BRNICS'),$port,$port)?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
:eth_bridging_members_help:
|
||||
|
||||
</div>
|
||||
_(Network protocol)_:
|
||||
: <select name="PROTOCOL:0" onchange="selectProtocol(this.form,'ethX',0)">
|
||||
<?=mk_option(_var($ethX,"PROTOCOL:0"), 'ipv4', _('IPv4 only'))?>
|
||||
<?=mk_option(_var($ethX,"PROTOCOL:0"), 'ipv6', _('IPv6 only'))?>
|
||||
<?=mk_option(_var($ethX,"PROTOCOL:0"), 'ipv4+ipv6', _('IPv4 + IPv6'))?>
|
||||
</select>
|
||||
|
||||
:eth_network_protocol_help:
|
||||
|
||||
<div markdown="1" class="ipv4-ethX-0" style="display:none">
|
||||
_(IPv4 address assignment)_:
|
||||
: <select name="USE_DHCP:0" onchange="selectProtocol(this.form,'ethX',0)">
|
||||
<?=mk_option(_var($ethX,"USE_DHCP:0"), 'yes', _('Automatic'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP:0"), 'no', _('Static'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP:0"), '', _('None'))?>
|
||||
</select>
|
||||
|
||||
:eth_ipv4_address_assignment_help:
|
||||
|
||||
<div markdown="1" class="more-ipv4-ethX-0" style="display:none">
|
||||
_(IPv4 address)_:
|
||||
: <input type="text" name="IPADDR:0" maxlength="15" value="<?=_var($ethX,"IPADDR:0")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">/<select name="NETMASK:0" class="slim">
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.0.0.0", "8")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.0.0", "16")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.128.0", "17")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.192.0", "18")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.224.0", "19")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.240.0", "20")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.248.0", "21")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.252.0", "22")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.254.0", "23")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.255.0", "24", _var($ethX,"IPADDR:0")?"":"selected")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.255.128", "25")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.255.192", "26")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.255.224", "27")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.255.240", "28")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.255.248", "29")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:0"), "255.255.255.252", "30")?>
|
||||
</select>
|
||||
|
||||
:eth_ipv4_address_help:
|
||||
|
||||
_(IPv4 default gateway)_:
|
||||
: <input type="text" name="GATEWAY:0" maxlength="15" value="<?=_var($ethX,"GATEWAY:0")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
<input type="text" name="METRIC:0" min="0" max="9999" value="<?=_var($ethX,"METRIC:0")?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *_(optional metric (lowest is preferred, 0 is no default gateway))_*
|
||||
|
||||
:eth_ipv4_default_gateway_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div markdown="1" class="ipv6-ethX-0" style="display:none">
|
||||
_(IPv6 address assignment)_:
|
||||
: <select name="USE_DHCP6:0" onchange="selectProtocol(this.form,'ethX',0)">
|
||||
<?=mk_option(_var($ethX,"USE_DHCP6:0"), 'yes', _('Automatic'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP6:0"), 'no', _('Static'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP6:0"), '', _('None'))?>
|
||||
</select>
|
||||
|
||||
:eth_ipv6_address_assignment_help:
|
||||
|
||||
<div markdown="1" class="more-ipv6-ethX-0" style="display:none">
|
||||
_(IPv6 address)_:
|
||||
: <input type="text" name="IPADDR6:0" maxlength="39" value="<?=_var($ethX,"IPADDR6:0")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">/<input type="number" name="NETMASK6:0" min="1" max="128" value="<?=_var($ethX,"NETMASK6:0")?>" class="slim">
|
||||
|
||||
:eth_ipv6_address_help:
|
||||
|
||||
_(IPv6 default gateway)_:
|
||||
: <input type="text" name="GATEWAY6:0" maxlength="39" value="<?=_var($ethX,"GATEWAY6:0")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
<input type="text" name="METRIC6:0" min="0" max="9999" value="<?=_var($ethX,"METRIC6:0")?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *_(optional metric (lowest is preferred, 0 is no default gateway))_*
|
||||
|
||||
:eth_ipv6_default_gateway_help:
|
||||
|
||||
_(IPv6 privacy extensions)_:
|
||||
: <select name="PRIVACY6:0">
|
||||
<?=mk_option(_var($ethX,"PRIVACY6:0"), "0", _("Disabled"))?>
|
||||
<?=mk_option(_var($ethX,"PRIVACY6:0"), "2", _("Enabled"))?>
|
||||
</select>
|
||||
|
||||
:eth_ipv6_privacy_extensions_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
_(Desired MTU)_:
|
||||
: <input type="number" name="MTU" min="68" max="9198" value="<?=_var($ethX,'MTU')?>" class="narrow" placeholder="1500">
|
||||
|
||||
:eth_desired_mtu_help:
|
||||
|
||||
_(Enable VLANs)_:
|
||||
: <select name="TYPE" onchange="checkNetworkAccess(this.form,'ethX')">
|
||||
<?=mk_option(_var($ethX,'TYPE'), 'access', _('No'))?>
|
||||
<?=mk_option(_var($ethX,'TYPE'), 'trunk', _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:eth_enable_vlans_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div id='index-ethX-0'></div>
|
||||
<?foreach ($vlan_ethX as $i):?>
|
||||
<div markdown="1" id="index-ethX-<?=$i?>" class="access-ethX shade-<?=$display['theme']?>" style="display:none">
|
||||
_(Interface description)_:
|
||||
: <span class="status vshift"><i id="tag-ethX-<?=$i?>" class="fa fa-fw fa-chevron-down" style="cursor:pointer" onclick="viewToggle('ethX','<?=$i?>')"></i></span>
|
||||
<input type="text" name="DESCRIPTION:<?=$i?>" maxlength="80" value="<?=htmlspecialchars(_var($ethX,"DESCRIPTION:$i"))?>" oninput="noRun(this.form)">
|
||||
|
||||
:eth_interface_description_help:
|
||||
|
||||
<div markdown="1" id="view-ethX-<?=$i?>" style="display:none">
|
||||
_(VLAN number)_:
|
||||
: <input type="number" name="VLANID:<?=$i?>" min="1" max="4095" value="<?=_var($ethX,"VLANID:$i")?>" class="narrow gap" required>
|
||||
<?if (!$service):?><input type="button" class="form" value="_(Delete VLAN)_" onclick="removeVLAN($('#index-ethX-<?=$i?>'))"><?endif;?>
|
||||
|
||||
:eth_vlan_number_help:
|
||||
|
||||
_(Network protocol)_:
|
||||
: <select name="PROTOCOL:<?=$i?>" onchange="selectProtocol(this.form,'ethX',<?=$i?>)">
|
||||
<?=mk_option(_var($ethX,"PROTOCOL:$i"), 'ipv4', _('IPv4 only'))?>
|
||||
<?=mk_option(_var($ethX,"PROTOCOL:$i"), 'ipv6', _('IPv6 only'))?>
|
||||
<?=mk_option(_var($ethX,"PROTOCOL:$i"), 'ipv4+ipv6', _('IPv4 + IPv6'))?>
|
||||
</select>
|
||||
|
||||
:eth_network_protocol_help:
|
||||
|
||||
<div markdown="1" class="ipv4-ethX-<?=$i?>" style="display:none">
|
||||
_(IPv4 address assignment)_:
|
||||
: <select name="USE_DHCP:<?=$i?>" onchange="selectProtocol(this.form,'ethX',<?=$i?>)">
|
||||
<?=mk_option(_var($ethX,"USE_DHCP:$i"), 'yes', _('Automatic'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP:$i"), 'no', _('Static'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP:$i"), '', _('None'))?>
|
||||
</select>
|
||||
|
||||
:eth_ipv4_address_assignment_help:
|
||||
|
||||
<div markdown="1" class="more-ipv4-ethX-<?=$i?>" style="display:none">
|
||||
_(IPv4 address)_:
|
||||
: <input type="text" name="IPADDR:<?=$i?>" maxlength="15" value="<?=_var($ethX,"IPADDR:$i")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">/<select name="NETMASK:<?=$i?>" class="slim">
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.0.0.0", "8")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.0.0", "16")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.128.0", "17")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.192.0", "18")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.224.0", "19")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.240.0", "20")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.248.0", "21")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.252.0", "22")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.254.0", "23")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.255.0", "24", isset($ethX["IPADDR:$i"])?"":"selected")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.255.128", "25")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.255.192", "26")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.255.224", "27")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.255.240", "28")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.255.248", "29")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:$i"), "255.255.255.252", "30")?>
|
||||
</select>
|
||||
|
||||
:eth_ipv4_address_help:
|
||||
|
||||
_(IPv4 default gateway)_:
|
||||
: <input type="text" name="GATEWAY:<?=$i?>" maxlength="15" value="<?=_var($ethX,"GATEWAY:$i")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
<input type="text" name="METRIC:<?=$i?>" min="0" max="9999" value="<?=_var($ethX,"METRIC:$i")?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *_(optional metric (lowest is preferred, 0 is no default gateway))_*
|
||||
|
||||
:eth_ipv4_default_gateway_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div markdown="1" class="ipv6-ethX-<?=$i?>" style="display:none">
|
||||
_(IPv6 address assignment)_:
|
||||
: <select name="USE_DHCP6:<?=$i?>" onchange="selectProtocol(this.form,'ethX',<?=$i?>)">
|
||||
<?=mk_option(_var($ethX,"USE_DHCP6:$i"), 'yes', _('Automatic'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP6:$i"), 'no', _('Static'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP6:$i"), '', _('None'))?>
|
||||
</select>
|
||||
|
||||
:eth_ipv6_address_assignment_help:
|
||||
|
||||
<div markdown="1" class="more-ipv6-ethX-<?=$i?>" style="display:none">
|
||||
_(IPv6 address)_:
|
||||
: <input type="text" name="IPADDR6:<?=$i?>" maxlength="39" value="<?=_var($ethX,"IPADDR6:$i")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">/<input type="number" name="NETMASK6:<?=$i?>" min="1" max="128" value="<?=_var($ethX,"NETMASK6:$i")?>" class="slim">
|
||||
|
||||
:eth_ipv6_address_help:
|
||||
|
||||
_(IPv6 default gateway)_:
|
||||
: <input type="text" name="GATEWAY6:<?=$i?>" maxlength="39" value="<?=_var($ethX,"GATEWAY6:$i")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
<input type="text" name="METRIC6:<?=$i?>" min="0" max="9999" value="<?=_var($ethX,"METRIC6:$i")?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *_(optional metric (lowest is preferred, 0 is no default gateway))_*
|
||||
|
||||
:eth_ipv6_default_gateway_help:
|
||||
|
||||
_(IPv6 privacy extensions)_:
|
||||
: <select name="PRIVACY6:<?=$i?>">
|
||||
<?=mk_option(_var($ethX,"PRIVACY6:$i"), "0", _("Disabled"))?>
|
||||
<?=mk_option(_var($ethX,"PRIVACY6:$i"), "2", _("Enabled"))?>
|
||||
</select>
|
||||
|
||||
:eth_ipv6_privacy_extensions_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?endforeach;?>
|
||||
|
||||
|
||||
: <input type="submit" value="_(Apply)_" onclick="$('#wait_<?=$tabbed?'eth0':'ethX'?>').show()" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
<input type="button" name="#shut_ethX" value="<?=_('Port '.$cmd)?>" onclick="portToggle('ethX','<?=$cmd?>')">
|
||||
<?if (!$service):?>
|
||||
<input type="button" class="access-ethX" value="_(Add VLAN)_" onclick="addVLAN('ethX')" style="display:none">
|
||||
<?else:?><?=sprintf(_('Stop **%s** to make changes, see'),$service).' (<a href="/Settings">'._('Settings').'</a>)'?><?endif;?>
|
||||
</form>
|
||||
|
||||
<script markdown="1" type="text/html" id="network-template-ethX">
|
||||
<div markdown="1" id="index-ethX-INDEX" class="access-ethX shade-<?=$display['theme']?>">
|
||||
_(Interface description)_:
|
||||
: <span class="status vshift"><i id="tag-ethX-INDEX" class="fa fa-fw fa-chevron-up" style="cursor:pointer" onclick="viewToggle('ethX','INDEX')"></i></span>
|
||||
<input type="text" name="DESCRIPTION:INDEX" maxlength="80" value="<?=htmlspecialchars(_var($ethX,"DESCRIPTION:INDEX"))?>" oninput="noRun(this.form)">
|
||||
|
||||
<div markdown="1" id="view-ethX-INDEX">
|
||||
_(VLAN number)_:
|
||||
: <input type="number" name="VLANID:INDEX" min="1" max="4095" value="<?=_var($ethX,"VLANID:INDEX")?>" class="narrow gap" required>
|
||||
<input type="button" class="form" value="_(Delete VLAN)_" onclick="removeVLAN($('#index-ethX-INDEX'))">
|
||||
|
||||
_(Network protocol)_:
|
||||
: <select name="PROTOCOL:INDEX" onchange="selectProtocol(this.form,'ethX',INDEX)">
|
||||
<?=mk_option(_var($ethX,"PROTOCOL:INDEX"), 'ipv4', _('IPv4 only'))?>
|
||||
<?=mk_option(_var($ethX,"PROTOCOL:INDEX"), 'ipv6', _('IPv6 only'))?>
|
||||
<?=mk_option(_var($ethX,"PROTOCOL:INDEX"), 'ipv4+ipv6', _('IPv4 + IPv6'))?>
|
||||
</select>
|
||||
|
||||
<div markdown="1" class="ipv4-ethX-INDEX" style="display:none">
|
||||
_(IPv4 address assignment)_:
|
||||
: <select name="USE_DHCP:INDEX" onchange="selectProtocol(this.form,'ethX',INDEX)">
|
||||
<?=mk_option(_var($ethX,"USE_DHCP:INDEX"), 'yes', _('Automatic'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP:INDEX"), 'no', _('Static'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP:INDEX"), '', _('None'))?>
|
||||
</select>
|
||||
|
||||
<div markdown="1" class="more-ipv4-ethX-INDEX" style="display:none">
|
||||
_(IPv4 address)_:
|
||||
: <input type="text" name="IPADDR:INDEX" maxlength="15" value="<?=_var($ethX,"IPADDR:INDEX")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">/<select name="NETMASK:INDEX" class="slim">
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.0.0.0", "8")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.0.0", "16")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.128.0", "17")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.192.0", "18")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.224.0", "19")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.240.0", "20")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.248.0", "21")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.252.0", "22")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.254.0", "23")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.255.0", "24", "selected")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.255.128", "25")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.255.192", "26")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.255.224", "27")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.255.240", "28")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.255.248", "29")?>
|
||||
<?=mk_option(_var($ethX,"NETMASK:INDEX"), "255.255.255.252", "30")?>
|
||||
</select>
|
||||
|
||||
_(IPv4 default gateway)_:
|
||||
: <input type="text" name="GATEWAY:INDEX" maxlength="15" value="<?=_var($ethX,"GATEWAY:INDEX")?>" class="narrow" pattern="<?=$validIP4?>" title="_(IPv4 address A.B.C.D)_">
|
||||
<input type="text" name="METRIC:INDEX" min="1" max="9999" value="<?=_var($ethX,"METRIC:INDEX")?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *_(optional metric (lowest is preferred, 0 is no default gateway))_*
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div markdown="1" class="ipv6-ethX-INDEX" style="display:none">
|
||||
_(IPv6 address assignment)_:
|
||||
: <select name="USE_DHCP6:INDEX" onchange="selectProtocol(this.form,'ethX',INDEX)">
|
||||
<?=mk_option(_var($ethX,"USE_DHCP6:INDEX"), 'yes', _('Automatic'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP6:INDEX"), 'no', _('Static'))?>
|
||||
<?=mk_option(_var($ethX,"USE_DHCP6:INDEX"), '', _('None'))?>
|
||||
</select>
|
||||
|
||||
<div markdown="1" class="more-ipv6-ethX-INDEX" style="display:none">
|
||||
_(IPv6 address)_:
|
||||
: <input type="text" name="IPADDR6:INDEX" maxlength="39" value="<?=_var($ethX,"IPADDR6:INDEX")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">/<input type="number" name="NETMASK6:INDEX" min="1" max="128" value="<?=_var($ethX,"NETMASK6:INDEX")?>" class="slim">
|
||||
|
||||
_(IPv6 default gateway)_:
|
||||
: <input type="text" name="GATEWAY6:INDEX" maxlength="39" value="<?=_var($ethX,"GATEWAY6:INDEX")?>" pattern="<?=$validIP6?>" title="_(IPv6 address nnnn:xxxx::yyyy)_">
|
||||
<input type="text" name="METRIC6:INDEX" min="1" max="9999" value="<?=_var($ethX,"METRIC6:INDEX")?>" class="slim"><i class="fa fa-sort-numeric-asc"></i> *_(optional metric (lowest is preferred, 0 is no default gateway))_*
|
||||
|
||||
_(IPv6 privacy extensions)_:
|
||||
: <select name="PRIVACY6:INDEX">
|
||||
<?=mk_option(_var($ethX,'PRIVACY6:INDEX'), "0", _("Disabled"))?>
|
||||
<?=mk_option(_var($ethX,'PRIVACY6:INDEX'), "2", _("Enabled"))?>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
@@ -0,0 +1,54 @@
|
||||
Menu="NetworkServices:999"
|
||||
Title="FTP Server"
|
||||
Icon="icon-ftp"
|
||||
Tag="globe"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$ftp_userlist_file = "/boot/config/vsftpd.user_list";
|
||||
$ftp_userlist = "";
|
||||
if (file_exists($ftp_userlist_file)) {
|
||||
$ftp_userlist = str_replace("\n", " ", trim(file_get_contents($ftp_userlist_file)));
|
||||
if ($ftp_userlist === false) $ftp_userlist = "";
|
||||
}
|
||||
$ftp_server = exec("lsof -i:21 -Pln|awk '/\(LISTEN\)/{print $2;exit}'") ? 1 : 0;
|
||||
?>
|
||||
<script>
|
||||
$(function() {
|
||||
showStatus('21');
|
||||
});
|
||||
</script>
|
||||
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame">
|
||||
<input type="hidden" name="#command" value="/webGui/scripts/ftpusers">
|
||||
|
||||
_(FTP server)_:
|
||||
: <select name="#arg[1]">
|
||||
<?=mk_option($ftp_server, "0", _("Disabled"))?>
|
||||
<?=mk_option($ftp_server, "1", _("Enabled"))?>
|
||||
</select>
|
||||
|
||||
:ftp_server_help:
|
||||
|
||||
_(FTP user(s))_:
|
||||
: <input type="text" name="#arg[2]" size="40" maxlength="80" value="<?=htmlspecialchars($ftp_userlist)?>">
|
||||
|
||||
:ftp_users_help:
|
||||
|
||||
|
||||
: <input type="submit" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
|
||||
</form>
|
||||
|
||||
:ftp_overview_help:
|
||||
@@ -0,0 +1,23 @@
|
||||
Menu="Buttons:4"
|
||||
Title="Feedback"
|
||||
Icon="icon-u-chat"
|
||||
Tag="icon-u-chat"
|
||||
Code="e93e"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2012-2022, 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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
function FeedbackButton() {
|
||||
openChanges("feedback", "_(Feedback)_", "feedback");
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,47 @@
|
||||
Type="xmenu"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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 clone_list($disk) {
|
||||
global $pools;
|
||||
return strpos($disk['status'],'_NP')===false && ($disk['type']=='Data' || in_array($disk['name'],$pools));
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
div.clone1{position:absolute;right:0;margin-top:0}
|
||||
div.clone2{position:absolute;right:0;margin-top:48px}
|
||||
<?if ($themes1):?>
|
||||
span.wrap{display:inline-block;width:128px}
|
||||
select.clone{min-width:123px;margin-right:0}
|
||||
<?else:?>
|
||||
span.wrap{display:inline-block;width:150px}
|
||||
select.clone{min-width:145px;margin-right:0}
|
||||
<?endif;?>
|
||||
input.clone{margin-left:8px;margin-right:0}
|
||||
span.clone,i.clone{margin-right:4px}
|
||||
</style>
|
||||
<script>
|
||||
function toggleButton(button,id) {
|
||||
var disabled = true;
|
||||
switch (id) {
|
||||
case false:
|
||||
case true:
|
||||
disabled = id;
|
||||
break;
|
||||
default:
|
||||
$('select#'+id+' option').each(function(){if ($(this).prop('selected')==true) disabled = false;});
|
||||
}
|
||||
$('input#'+button).prop('disabled',disabled);
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,71 @@
|
||||
Menu="Flash"
|
||||
Title="Flash Device Settings"
|
||||
Tag="usb"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
function cleanUp(zip) {
|
||||
if (document.hasFocus()) {
|
||||
$('input[value="_(Creating Flash backup)_..."]').val("_(Flash backup)_").prop('disabled',false);
|
||||
$('div.spinner').hide('slow');
|
||||
$('#pleaseWait').hide('slow');
|
||||
$.post('/webGui/include/Download.php',{cmd:'unlink',file:zip});
|
||||
} else {
|
||||
setTimeout(function(){cleanUp(zip);},2000);
|
||||
}
|
||||
}
|
||||
function backup() {
|
||||
$('input[value="_(Flash backup)_"]').val('_(Creating Flash backup)_...').prop('disabled',true);
|
||||
$('div.spinner').show('slow');
|
||||
$('#pleaseWait').show('slow');
|
||||
$.post('/webGui/include/Download.php',{cmd:'backup'},function(zip) {
|
||||
if (zip) {
|
||||
location = '/'+zip;
|
||||
setTimeout(function(){cleanUp(zip);},6000);
|
||||
} else {
|
||||
$('input[value="_(Creating Flash backup)_..."]').val("_(Flash backup)_");
|
||||
$('div.spinner').hide('slow');
|
||||
$('#pleaseWait').hide('slow');
|
||||
swal({title:"_(Creation error)_",text:"_(Insufficient free disk space available)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<div id="pleaseWait" style="display:none;text-align:center;margin-bottom:24px"><span class="red-text strong">_(Please wait)_... _(creating Flash backup zip file (this may take several minutes))_</span></div>
|
||||
|
||||
_(Flash Vendor)_:
|
||||
: <?=$var['flashVendor'];?>
|
||||
|
||||
_(Flash Product)_:
|
||||
: <?=$var['flashProduct'];?>
|
||||
|
||||
_(Flash GUID)_:
|
||||
: <?=$var['flashGUID'];?>
|
||||
|
||||
<?if (strstr($var['regTy'], "blacklisted")):?>
|
||||
|
||||
|
||||
: **_(Blacklisted)_** - <a href="http://lime-technology.com/contact" target="_blank">_(Contact Support)_</a>
|
||||
|
||||
<?else:?>
|
||||
|
||||
|
||||
: [_(Registration Key Manager)_](/Tools/Registration)
|
||||
|
||||
<?endif;?>
|
||||
|
||||
:flash_backup_help:
|
||||
|
||||
|
||||
: <input type="button" value="_(Flash backup)_" onclick="backup()"><input type="button" value="_(Done)_" onclick="done()">
|
||||
@@ -0,0 +1,74 @@
|
||||
Menu="UNRAID-OS"
|
||||
Title="Hardware Profile"
|
||||
Icon="icon-profile"
|
||||
Tag="wrench"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$var = parse_ini_file('state/var.ini');
|
||||
$keyfile = trim(base64_encode(@file_get_contents($var['regFILE'])));
|
||||
?>
|
||||
|
||||
<script>
|
||||
function toggle_hw() {
|
||||
if ($('#hw_details a').html()=="_(Show Details)_") {
|
||||
$.getJSON('/webGui/include/HardwareCollect.php',function(hwdata) {
|
||||
$('#hw_details a').html("_(Hide Details)_");
|
||||
$('#hw_details pre').text(hwdata.hwxml).slideDown('fast');
|
||||
});
|
||||
} else {
|
||||
$('#hw_details a').html("_(Show Details)_");
|
||||
$('#hw_details pre').slideUp('fast', function(){$(this).html('');});
|
||||
}
|
||||
}
|
||||
function upload() {
|
||||
$('input[value="Upload"]').val('_(Uploading)_...').prop('disabled',true);
|
||||
$('#pleaseWait').show('fast');
|
||||
|
||||
$.getJSON('/webGui/include/HardwareCollect.php',function(hwdata) {
|
||||
$.post('https://keys.lime-technology.com/account/hwprofile/upload',{keyfile:hwdata.keyfile,osversion:hwdata.osversion,hwxml:hwdata.hwxml},function(data) {
|
||||
$('#pleaseWait').hide().html(data.message).fadeIn('fast');
|
||||
$('input[value="_(Uploading)_..."]').val('_(Uploaded)_!');
|
||||
}).fail(function(data) {
|
||||
var msg = "<p>_(Sorry, an error occurred)_. _(Please try again later)_.</p>";
|
||||
$('#pleaseWait').hide().html(msg).fadeIn('fast');
|
||||
$('input[value="_(Uploading)_..."]').val("_(Upload)_").prop('disabled',false);
|
||||
});
|
||||
});
|
||||
}
|
||||
$(function() {
|
||||
$.getJSON('https://keys.lime-technology.com/account/hwprofile/status',{keyfile:'<?=$keyfile?>'},function(status) {
|
||||
if (status.last_submitted) {
|
||||
var d = new Date(status.last_submitted * 1000);
|
||||
$('#lastUploaded').html("_(Your hardware profile was last submitted on)_ " + d.toLocaleDateString()).fadeIn('fast');
|
||||
} else {
|
||||
$('#lastUploaded').html("_(You haven't sent Limetech your hardware profile yet)_").fadeIn('fast');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
_(This utility is used for troubleshooting purposes)_. _(It will collect all of the system hardware information, remove any serial numbers, and securely upload it to LimeTech)_.
|
||||
|
||||
<div id="hw_details">
|
||||
<pre style="display:none;max-height:300px;overflow-y:auto"></pre>
|
||||
<a href="#" onclick="toggle_hw();return false;">_(Show Details)_</a>
|
||||
</div>
|
||||
|
||||
*_(No personal information such as user names, passwords, or any other file contents is included in the hardware profile)_.*
|
||||
|
||||
<div id="lastUploaded" style="color:grey"></div>
|
||||
|
||||
<input type="button" value="_(Upload)_" onclick="upload()"><input type="button" value="_(Done)_" onclick="done()">
|
||||
|
||||
<br><div id="pleaseWait" style="display:none;font-weight:bold;color:blue;text-align:center">_(Please wait)_... _(uploading hardware information)_ (_(this may take several minutes)_)</div>
|
||||
@@ -0,0 +1,28 @@
|
||||
Menu="Buttons:7"
|
||||
Title="Help"
|
||||
Icon="icon-u-help"
|
||||
Code="e934"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
function HelpButton() {
|
||||
if ($('.nav-item.HelpButton').toggleClass('active').hasClass('active')) {
|
||||
$('.inline_help').show('slow');
|
||||
$.cookie('help','help');
|
||||
} else {
|
||||
$('.inline_help').hide('slow');
|
||||
$.removeCookie('help');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,58 @@
|
||||
Menu="OtherSettings"
|
||||
Type="xmenu"
|
||||
Title="Identification"
|
||||
Icon="icon-home"
|
||||
Tag="home"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$disabled = $var['fsState']!='Stopped' ? 'disabled' : '';
|
||||
$name_regex = '^[A-Za-z0-9]([A-Za-z0-9\-\.]{0,13}[A-Za-z0-9])?$';
|
||||
$name_warn = preg_match('/'.$name_regex.'/', $var['NAME']) ? 'none' : 'block';
|
||||
?>
|
||||
<form markdown="1" name="NameSettings" method="POST" action="/update.htm" target="progressFrame">
|
||||
<input type="hidden" name="server_https" value="<?=_var($_SERVER,'HTTPS')?>">
|
||||
<input type="hidden" name="server_name" value="<?=_var($_SERVER,'HTTP_HOST')?>">
|
||||
<input type="hidden" name="server_addr" value="<?=_var($_SERVER,'SERVER_ADDR')?>">
|
||||
|
||||
_(Server name)_:
|
||||
: <input type="text" name="NAME" id="NAME" maxlength="15" pattern="<?=$name_regex?>" value="<?=htmlspecialchars(_var($var,'NAME'))?>" title="_(Only alphanumeric characters)_ ("A-Z", "a-z", and "0-9"), dashes ("-"), and dots ("."); _(and, the first and last characters must be alphanumeric)_" <?=$disabled?> required> <span id="name_warning" style="display:<?=$name_warn?>"><i class="fa fa-warning icon warning"></i> _(Not compatible with NetBIOS)_</span>
|
||||
|
||||
:id_server_name_help:
|
||||
|
||||
_(Description)_:
|
||||
: <input type="text" name="COMMENT" value="<?=htmlspecialchars(_var($var,'COMMENT'))?>" <?=$disabled?>>
|
||||
|
||||
:id_description_help:
|
||||
|
||||
_(Model)_:
|
||||
: <input type="text" name="SYS_MODEL" value="<?=htmlspecialchars(_var($var,'SYS_MODEL'))?>" <?=$disabled?>>
|
||||
|
||||
:id_model_help:
|
||||
|
||||
|
||||
: <input type="submit" name="changeNames" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()"><?if ($disabled):?>*_(Array must be **Stopped** to change)_*<?endif;?>
|
||||
</form>
|
||||
<script>
|
||||
$("#NAME").keypress(function(event) {
|
||||
return event.key.match(/[A-Za-z0-9\-\.]/)!==null;
|
||||
});
|
||||
$("#NAME").on("input change", function() {
|
||||
if ($(this).val().match(/<?=$name_regex;?>/) === null) {
|
||||
$('#name_warning').fadeIn('fast');
|
||||
} else {
|
||||
$('#name_warning').fadeOut('fast');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,22 @@
|
||||
Menu="Buttons:5"
|
||||
Title="Info"
|
||||
Icon="icon-u-display"
|
||||
Code="e930"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2012-2022, 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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
function InfoButton() {
|
||||
openChanges("system_information", "_(System Information)_", "sysinfo");
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,34 @@
|
||||
Menu="Registration"
|
||||
Title="Install Key"
|
||||
Tag="flag"
|
||||
Cond="($var['regTy']!='Pro')"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
?>
|
||||
<style>
|
||||
span.info{margin-left:12px}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function installKey(file) {
|
||||
file = file.trim();
|
||||
if (file) openPlugin('install_key '+encodeURIComponent(file), "_(Install Key)_");
|
||||
}
|
||||
</script>
|
||||
|
||||
<form markdown="1">
|
||||
<span class="info">_(To install a registration key, paste the key file URL in the box below and click **Install Key**)_.</span>
|
||||
|
||||
_(Key file URL)_:
|
||||
: <input type="text" name="file" id="key_file" maxlength="1024" value="" style="width:33%">
|
||||
<input type="button" value="_(Install Key)_" onclick="installKey(this.form.file.value.trim())">
|
||||
</form>
|
||||
@@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
@@ -0,0 +1,132 @@
|
||||
Menu="WebGui"
|
||||
Title="Language"
|
||||
Icon="icon-language"
|
||||
Tag="icon-language"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2012-2022, 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
|
||||
$installed = ['English'];
|
||||
$plugins = '/var/log/plugins';
|
||||
|
||||
$keys = parse_ini_file('webGui/include/languages.key',false,INI_SCANNER_RAW);
|
||||
$head = '<i class="fa fa-fw fa-trash" title="_(Remove the installed language)_" style="cursor:pointer" onclick="remove("';
|
||||
$tail = '")"></i>';
|
||||
|
||||
foreach (glob("$plugins/lang-*.xml",GLOB_NOSORT) as $xml_file) $installed[] = language('LanguageLocal',$xml_file).$head.str_replace('lang-','',basename($xml_file,'.xml')).$tail;
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.switchbutton.css')?>">
|
||||
<style>
|
||||
select.wide{min-width:<?=$themes2?'314':'300'?>px}
|
||||
div.notice{margin-top:70px;margin-bottom:30px}
|
||||
div#selectlang{margin-top:20px}
|
||||
label.button{font-family:clear-sans;font-size:1.1rem;font-weight:bold;letter-spacing:1.8px;text-transform:uppercase;min-width:86px;margin:0;padding:8px;text-align:center;text-decoration:none;white-space:nowrap;cursor:pointer;outline:none;border-radius:4px;border:none;color:#ff8c2f;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 0 no-repeat,-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#e22828),to(#e22828)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#ff8c2f),to(#ff8c2f)) 100% 100% no-repeat;background:linear-gradient(90deg,#e22828 0,#ff8c2f) 0 0 no-repeat,linear-gradient(90deg,#e22828 0,#ff8c2f) 0 100% no-repeat,linear-gradient(0deg,#e22828 0,#e22828) 0 100% no-repeat,linear-gradient(0deg,#ff8c2f 0,#ff8c2f) 100% 100% no-repeat;background-size:100% 2px,100% 2px,2px 100%,2px 100%}
|
||||
label.button:hover{color:#f2f2f2;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f));background:linear-gradient(90deg,#e22828 0,#ff8c2f)}
|
||||
</style>
|
||||
|
||||
<script src="<?autov('/webGui/javascript/jquery.switchbutton.js')?>"></script>
|
||||
<script>
|
||||
function execute(cmd,title,language,name,filedata) {
|
||||
var keys = {};
|
||||
<?foreach ($keys as $key => $name) echo "keys['$key'] = '".strtok($keys[$key],' (')."'\n";?>
|
||||
$.post("/webGui/include/FileUpload.php",{cmd:cmd,filename:language,name:encodeURIComponent(name),filedata:filedata},function(list){
|
||||
if (list.indexOf('Error 500')==-1) {
|
||||
var installed = [];
|
||||
if (list.length) {
|
||||
var name = list.split(',');
|
||||
for (var i=0; i < name.length; i++) installed.push(keys[name[i]]+(name[i]!='en_US'? '<?=$head?>'+name[i]+'<?=$tail?>' : ''));
|
||||
}
|
||||
$('.installed').html(installed.join(', '));
|
||||
swal({title:title,text:"_(See)_ <a href='/Settings/DisplaySettings'>_(Display Settings)_</a> _(to select your language)_",type:'success',html:true,confirmButtonText:"_(Ok)_"});
|
||||
$('#uploadbutton').prop('disabled',true);
|
||||
}
|
||||
});
|
||||
}
|
||||
function remove(language) {
|
||||
execute('rm', "_(Language support deleted)_", language, '', '');
|
||||
}
|
||||
function upload(form) {
|
||||
var language = form.language;
|
||||
if (!language.value) {
|
||||
swal({title:"_(Missing Language)_",text:"_(Please select a language before proceeding)_!",type:'error',html:true,confirmButtonText:"_(Ok)_"});
|
||||
return;
|
||||
}
|
||||
execute('add', "_(Language support added)_", language.value, language.options[language.selectedIndex].text, form.file.value);
|
||||
}
|
||||
function getZIPfile(event,form) {
|
||||
var input = event.target;
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(){
|
||||
var name = input.files[0].name;
|
||||
if (name.slice(-4)=='.zip') {
|
||||
form.file.value = reader.result;
|
||||
$('#uploadbutton').prop('disabled',false);
|
||||
for (var n = 0; n < form.language.length; n++) if (form.language.options[n].text.indexOf(name.slice(0,-4))>0) {form.language.selectedIndex = n; break;}
|
||||
} else {
|
||||
swal({title:"_(Wrong File Extension)_",text:"_(Only ZIP files are allowed)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
|
||||
}
|
||||
};
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
}
|
||||
function installXML(name) {
|
||||
var file = name.trim();
|
||||
if (file) openPlugin('language install '+file, "_(Install Language)_");
|
||||
}
|
||||
$(function() {
|
||||
$('input.view').switchButton({labels_placement:'left', off_label:"_(User)_", on_label:"_(Developer)_"});
|
||||
$('input.view').change(function(){$('.user,.developer').toggle('slow');});
|
||||
});
|
||||
</script>
|
||||
<span class="status vhshift"><input type="checkbox" class="view"></span>
|
||||
|
||||
<div markdown="1" class="user">
|
||||
<div class="notice">_(Use this to install official language packs)_</div>
|
||||
_(Installed languages)_:
|
||||
: <span class="installed"><?=implode(', ',$installed)?></span>
|
||||
|
||||
_(Enter URL of language pack XML file)_
|
||||
:
|
||||
|
||||
<dl>
|
||||
<form name="xml_install" method="POST" target="progressFrame">
|
||||
<dt><input type="text" name="file" id="xml_file" maxlength="1024" value="" style="width:90%"></dt>
|
||||
<dd><input type="button" value="_(Install)_" onclick="installXML(this.form.file.value)" style="margin:0"></dd>
|
||||
</form>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div markdown="1" class="developer" style="display:none">
|
||||
<div class="notice">_(Use this to develop language packs)_</div>
|
||||
<form markdown="1">
|
||||
<input type="hidden" name="file" value="">
|
||||
|
||||
_(Installed languages)_:
|
||||
: <span class="installed"><?=implode(', ',$installed)?></span>
|
||||
|
||||
_(Select language)_:
|
||||
: <select name="language" class="wide">
|
||||
<?=mk_option(1, "", "---")?>
|
||||
<?foreach ($keys as $key => $name) echo mk_option(1, $key, $name)?>
|
||||
</select>
|
||||
|
||||
<div id="selectlang" markdown="1">
|
||||
_(Select language file)_:
|
||||
: <span><label for="files" class="button">_(Browse)_</label><input id="files" type="file" style="display:none" accept=".zip" onchange="getZIPfile(event,this.form)"></span>
|
||||
|
||||
</div>
|
||||
|
||||
: <input id="uploadbutton" type="button" value="_(Upload)_" onclick="upload(this.form)" disabled><input type="button" value="_(Done)_" class="lock" onclick="done()">
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,38 @@
|
||||
Menu="Buttons:1"
|
||||
Title="Switch Language"
|
||||
Icon="icon-u-switch"
|
||||
Code="e982"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
<?if (count(glob('/var/log/plugins/lang-*.xml'))==0):?>
|
||||
// hide switch button when no other language packs
|
||||
$(function(){$('.nav-item.LanguageButton').hide();});
|
||||
<?endif;?>
|
||||
|
||||
function LanguageButton() {
|
||||
var locale = '<?=$locale?>';
|
||||
if (locale) {
|
||||
switchLanguage('');
|
||||
$.cookie('locale',locale);
|
||||
} else {
|
||||
switchLanguage($.cookie('locale'));
|
||||
$.removeCookie('locale');
|
||||
}
|
||||
}
|
||||
|
||||
function switchLanguage(lang) {
|
||||
$.post('/webGui/include/LanguageReset.php',{lang:lang},function(){location.reload();});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,22 @@
|
||||
Menu="Buttons:6"
|
||||
Title="Log"
|
||||
Icon="icon-u-log"
|
||||
Code="e936"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
* Copyright 2012-2021, 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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
function LogButton() {
|
||||
openTerminal('syslog','syslog','');
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,25 @@
|
||||
Menu="Buttons:2"
|
||||
Title="Logout"
|
||||
Icon="icon-u-logout"
|
||||
Code="e937"
|
||||
Cond="$_SERVER['HTTP_HOST']!='localhost'"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
function LogoutButton() {
|
||||
var id = window.setTimeout(null,0);
|
||||
while (id--) window.clearTimeout(id);
|
||||
window.location.href = '/logout';
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,4 @@
|
||||
Menu="Tasks:1"
|
||||
Type="xmenu"
|
||||
Code="e908"
|
||||
Load="30"
|
||||
@@ -0,0 +1,454 @@
|
||||
Menu="OtherSettings"
|
||||
Type="xmenu"
|
||||
Title="Management Access"
|
||||
Icon="icon-key"
|
||||
Tag="expeditedssl"
|
||||
---
|
||||
<?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 find_tasks() {
|
||||
global $site;
|
||||
$tasks = [];
|
||||
foreach ($site as $page) {
|
||||
if (empty($page['Menu'])) continue;
|
||||
$menu = strtok($page['Menu'], ' ');
|
||||
switch ($menu[0]) {
|
||||
case '$': $menu = get_ini_key($menu,strtok(' ')); break;
|
||||
case '/': $menu = get_file_key($menu,strtok(' ')); break;
|
||||
}
|
||||
while ($menu !== false) {
|
||||
if (substr($menu,0,5) == 'Tasks') {
|
||||
if (empty($page['Cond'])) $tasks[] = $page['name'];
|
||||
break;
|
||||
}
|
||||
$menu = strtok(' ');
|
||||
}
|
||||
}
|
||||
sort($tasks);
|
||||
return $tasks;
|
||||
}
|
||||
function acceptableCert($certFile, $hostname, $expectedURL) {
|
||||
if (!file_exists($certFile)) return false;
|
||||
$certURLs=null;
|
||||
// get Subject URL and all SAN URLs from cert
|
||||
exec("openssl x509 -noout -subject -nameopt multiline -in $certFile | sed -n 's/ *commonName *= //p' ; openssl x509 -noout -ext subjectAltName -in $certFile | grep -Eo \"DNS:[a-zA-Z 0-9.*-]*\" | sed \"s/DNS://g\"", $certURLs);
|
||||
foreach($certURLs as $certURL) {
|
||||
// adjust for wildcard certs
|
||||
$certURL = str_replace('*', $hostname, $certURL);
|
||||
// case-insensitive compare
|
||||
if (strcasecmp($certURL, $expectedURL) == 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
$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'));
|
||||
$cert2Issuer = '';
|
||||
$isLEcert = false;
|
||||
if ($keyfile !== false) $keyfile = base64_encode($keyfile);
|
||||
|
||||
// self-signed or user-provided cert
|
||||
$cert1File = "/boot/config/ssl/certs/"._var($var,'NAME','tower')."_unraid_bundle.pem";
|
||||
$cert1Present = file_exists("$cert1File");
|
||||
$cert1SelfSigned = $cert1URLvalid = false;
|
||||
$cert1Issuer = ' ';
|
||||
|
||||
if ($cert1Present) {
|
||||
$cert1URL = _var($var,'NAME','tower').(_var($var,'LOCAL_TLD') ? '.'._var($var,'LOCAL_TLD') : '');
|
||||
// if user replaced cert without reloading nginx, the cert on the flash could be invalid
|
||||
$cert1URLvalid = acceptableCert($cert1File, _var($var,'NAME','tower'), $cert1URL);
|
||||
$cert1Subject = exec("/usr/bin/openssl x509 -in $cert1File -noout -text | sed -n 's/^.*Subject: //p'");
|
||||
$cert1Issuer = exec("/usr/bin/openssl x509 -in $cert1File -noout -text | sed -n -e 's/^.*Issuer: //p'");
|
||||
$cert1Expires = exec("/usr/bin/openssl x509 -in $cert1File -noout -text | sed -n -e 's/^.*Not After : //p'");
|
||||
$cert1SelfSigned = ($cert1Subject == $cert1Issuer);
|
||||
}
|
||||
|
||||
// unraid.net, myunraid.net LE cert. could potentially be user provided as well
|
||||
$cert2File = "/boot/config/ssl/certs/certificate_bundle.pem";
|
||||
$cert2Present = file_exists("$cert2File");
|
||||
if ($cert2Present) {
|
||||
$cert2Subject = exec("/usr/bin/openssl x509 -in $cert2File -noout -subject -nameopt multiline 2>/dev/null|sed -n 's/ *commonName *= //p'");
|
||||
$cert2Issuer = exec("/usr/bin/openssl x509 -in $cert2File -noout -text | sed -n -e 's/^.*Issuer: //p'");
|
||||
$cert2Expires = exec("/usr/bin/openssl x509 -in $cert2File -noout -text | sed -n -e 's/^.*Not After : //p'");
|
||||
$isLegacyCert = preg_match('/.*\.unraid\.net$/', $cert2Subject);
|
||||
$isWildcardCert = preg_match('/.*\.myunraid\.net$/', $cert2Subject);
|
||||
$isLEcert = $isLegacyCert || $isWildcardCert;
|
||||
$subject2URL = $cert2Subject;
|
||||
if ($isWildcardCert) {
|
||||
if (!$addr)
|
||||
// if eth0 doesn't have an IP address, then show noip.hash.myunraid.net as a placeholder url
|
||||
$subject2URL = str_replace("*", 'noip', $subject2URL);
|
||||
elseif (strpos($addr, ":") === false)
|
||||
$subject2URL = str_replace("*", str_replace(".", "-", $addr), $subject2URL);
|
||||
else
|
||||
$subject2URL = str_replace("*", str_replace(":", "-", $addr), $subject2URL);
|
||||
}
|
||||
if ($isLEcert) {
|
||||
exec("openssl x509 -checkend 2592000 -noout -in $cert2File 2>/dev/null", $arrout, $retval_expired);
|
||||
if (!$addr) {
|
||||
$dnsValid = false;
|
||||
$dnsRebindingProtection = false;
|
||||
} elseif (strpos($addr, ":") === false) {
|
||||
$rebindtest_ip = exec("host -4 -t A rebindtest4.myunraid.net 2>/dev/null|awk '{print \$4}'");
|
||||
$dnsRebindingProtection = ($rebindtest_ip != "192.168.42.42");
|
||||
if (!$dnsRebindingProtection) {
|
||||
$cert_ip = exec("host -4 -t A $subject2URL 2>/dev/null|awk '{print \$4}'");
|
||||
$dnsValid = $cert_ip==$addr;
|
||||
}
|
||||
} else {
|
||||
$rebindtest_ip = exec("host -6 -t AAAA rebindtest6.myunraid.net 2>/dev/null|awk '{print \$4}'");
|
||||
// more: restore this after TTL expires
|
||||
// $dnsRebindingProtection = ($rebindtest_ip != "fd42::42");
|
||||
$dnsRebindingProtection = ($rebindtest_ip != "fd42::42") && ($rebindtest_ip != "fd42::");
|
||||
if (!$dnsRebindingProtection) {
|
||||
$cert_ip = exec("host -6 -t AAAA $subject2URL 2>/dev/null|awk '{print \$4}'");
|
||||
$dnsValid = $cert_ip==$addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$http_port = _var($var,'PORT',80) != 80 ? ":{$var['PORT']}" : '';
|
||||
$https_port = _var($var,'PORTSSL',443) != 443 ? ":{$var['PORTSSL']}" : '';
|
||||
$http_ip_url = "http://"._var($nginx,'NGINX_LANIP')."{$http_port}/";
|
||||
$https_ip_url = "https://"._var($nginx,'NGINX_LANIP')."{$https_port}/";
|
||||
$http_ip6_url = "http://"._var($nginx,'NGINX_LANIP6')."{$http_port}/";
|
||||
$https_ip6_url = "https://"._var($nginx,'NGINX_LANIP6')."{$https_port}/";
|
||||
$http_mdns_url = "http://"._var($nginx,'NGINX_LANMDNS')."{$http_port}/";
|
||||
$https_mdns_url = "https://"._var($nginx,'NGINX_LANMDNS')."{$https_port}/";
|
||||
$https_fqdn_url = "https://"._var($nginx,'NGINX_LANFQDN')."{$https_port}/";
|
||||
$https_fqdn6_url = "https://"._var($nginx,'NGINX_LANFQDN6')."{$https_port}/";
|
||||
|
||||
$urls = [];
|
||||
// push an array of four values into the $urls array:
|
||||
// 0 - the url
|
||||
// 1 - the url it redirects to, or null
|
||||
// 2 - the certificate file used, or null
|
||||
// 3 - self-signed certificate, or false
|
||||
|
||||
switch(_var($var,'USE_SSL','no')) {
|
||||
case 'no':
|
||||
if (!empty($nginx['NGINX_LANIP'])) $urls[] = [$http_ip_url, null, null, false];
|
||||
if (!empty($nginx['NGINX_LANIP6'])) $urls[] = [$http_ip6_url, null, null, false];
|
||||
if (!empty($nginx['NGINX_LANMDNS'])) $urls[] = [$http_mdns_url, null, null, false];
|
||||
if (!empty($nginx['NGINX_LANFQDN'])) $urls[] = [$https_fqdn_url, null, "certificate_bundle.pem", false];
|
||||
if (!empty($nginx['NGINX_LANFQDN6'])) $urls[] = [$https_fqdn6_url, null, "certificate_bundle.pem", false];
|
||||
break;
|
||||
case 'yes':
|
||||
if (!empty($nginx['NGINX_LANIP'])) $urls[] = [$http_ip_url, $https_ip_url, null, false];
|
||||
if (!empty($nginx['NGINX_LANIP'])) $urls[] = [$https_ip_url, null, "{$var['NAME']}_unraid_bundle.pem", $cert1SelfSigned];
|
||||
if (!empty($nginx['NGINX_LANIP6'])) $urls[] = [$http_ip6_url, $https_ip6_url, null, false];
|
||||
if (!empty($nginx['NGINX_LANIP6'])) $urls[] = [$https_ip6_url, null, "{$var['NAME']}_unraid_bundle.pem", $cert1SelfSigned];
|
||||
if (!empty($nginx['NGINX_LANMDNS'])) $urls[] = [$http_mdns_url, $https_mdns_url, null, false];
|
||||
if (!empty($nginx['NGINX_LANMDNS'])) $urls[] = [$https_mdns_url, null, "{$var['NAME']}_unraid_bundle.pem", $cert1SelfSigned];
|
||||
if (!empty($nginx['NGINX_LANFQDN'])) $urls[] = [$https_fqdn_url, null, "certificate_bundle.pem", false];
|
||||
if (!empty($nginx['NGINX_LANFQDN6'])) $urls[] = [$https_fqdn6_url, null, "certificate_bundle.pem", false];
|
||||
break;
|
||||
case 'auto': // aka strict
|
||||
if (!empty($nginx['NGINX_LANIP'])) $urls[] = [$http_ip_url, $https_fqdn_url, null, false];
|
||||
if (!empty($nginx['NGINX_LANIP6'])) $urls[] = [$http_ip6_url, $https_fqdn6_url, null, false];
|
||||
if (!empty($nginx['NGINX_LANMDNS'])) $urls[] = [$http_mdns_url, $https_fqdn_url, null, false];
|
||||
if (!empty($nginx['NGINX_LANFQDN'])) $urls[] = [$https_fqdn_url, null, "certificate_bundle.pem", false];
|
||||
if (!empty($nginx['NGINX_LANFQDN6'])) $urls[] = [$https_fqdn6_url, null, "certificate_bundle.pem", false];
|
||||
break;
|
||||
}
|
||||
|
||||
$cert_time_format = $display['date'].($display['date']!='%c' ? ', '.str_replace(['%M','%R'],['%M:%S','%R:%S'],$display['time']):'');
|
||||
$provisionlabel = $isLEcert ? _('Renew') : _('Provision');
|
||||
$disabled_provision = $keyfile===false || ($isLEcert && $retval_expired===0) || !$addr ? 'disabled' : '';
|
||||
$disabled_provision_msg = !$addr ? _('Ensure the primary network card eth0 has an IP address.') : '';
|
||||
$disabled_upgrade = !$addr ? 'disabled' : '';
|
||||
$disabled_updatedns = $keyfile!==false && $isLEcert ? '' : 'disabled';
|
||||
$disabled_delete = $cert2Present && $var['USE_SSL']!='auto' ? '' : 'disabled';
|
||||
$disabled_auto = $isLEcert && !$dnsRebindingProtection && $dnsValid ? '' : 'disabled';
|
||||
$upgradelabel = _('Upgrade Cert');
|
||||
|
||||
// Get ports in use
|
||||
$portsInUse = [];
|
||||
exec("lsof -Pni|awk '/LISTEN/ && \$9!~/127.0.0.1/ && \$9!~/\\[::1\\]/{print \$9}'|sort -u", $output);
|
||||
|
||||
$bind = false; //= $var['BIND_MGT']=='yes'; - not used in 6.10
|
||||
$list = ['*'];
|
||||
if ($addr) array_push($list, $addr);
|
||||
|
||||
foreach ($output as $line) {
|
||||
[$ip, $port] = my_explode($line[0]=='[' ? ']:' : ':',$line);
|
||||
if ($ip[0]=='[') $ip = substr($ip,1); // ipv6 address
|
||||
if (!in_array($port,$portsInUse) && (!$bind || in_array($ip,$list))) $portsInUse[] = $port;
|
||||
}
|
||||
sort($portsInUse,SORT_NUMERIC);
|
||||
?>
|
||||
<style>
|
||||
span.warning{margin-left:20px}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function provisionHandler(event, form) { // provisions and renewals require being Signed In to Unraid.net
|
||||
if (event.submitter.value === 'Delete') return true; // always allow deletes
|
||||
if (event.submitter.value === 'Renew') return true; // always allow renewals
|
||||
};
|
||||
|
||||
function updateDNS(button) {
|
||||
$(button).prop("disabled", true).html("<i class='fa fa-circle-o-notch fa-spin fa-fw'></i>_(Update DNS)_");
|
||||
var failure = function(data) {
|
||||
var status = data.status;
|
||||
var obj = data.responseJSON;
|
||||
var msg = "_(Sorry, an error occurred updating unraid.net DNS records)_. _(The error is)_: "+obj.error+".";
|
||||
$(button).prop("disabled", false).html("_(Update DNS)_");
|
||||
swal({title:"_(Oops)_",text:msg,type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
};
|
||||
var success = function(data) {
|
||||
$(button).prop("disabled", false).html("_(Update DNS)_");
|
||||
<?$text = _('Your local IP address %s has been updated for unraid.net')?>
|
||||
swal({title:"",text:"<?=sprintf($text,$addr)?>",type:"success",html:true,confirmButtonText:"_(Ok)_"});
|
||||
};
|
||||
$.post("/webGui/include/UpdateDNS.php",success).fail(failure);
|
||||
}
|
||||
|
||||
function checkPorts(form) {
|
||||
var portsInUse = [<?=implode(',',$portsInUse)?>];
|
||||
var range = [], list = [], duplicates = [];
|
||||
var checks = [
|
||||
{'key':"PORTTELNET", 'used':"<?=$var['USE_TELNET']=='yes'?>", 'port':"<?=$var['PORTTELNET']?>", 'default':"23" , 'name':"_(TELNET port)_"},
|
||||
{'key':"PORTSSH" , 'used':"<?=$var['USE_SSH']=='yes'?>" , 'port':"<?=$var['PORTSSH']?>" , 'default':"22" , 'name':"_(SSH port)_"},
|
||||
{'key':"PORT" , 'used':"<?=$var['USE_SSL']=='no'?>" , 'port':"<?=$var['PORT']?>" , 'default':"80" , 'name':"_(HTTP port)_"},
|
||||
{'key':"PORTSSL" , 'used':"<?=$var['USE_SSL']!='no'?>" , 'port':"<?=$var['PORTSSL']?>" , 'default':"443", 'name':"_(HTTPS port)_"}
|
||||
];
|
||||
for (var i=0,check; check=checks[i]; i++) {
|
||||
var item = $(form).find('input[name="'+check['key']+'"]');
|
||||
if ($(item).is(':disabled')) continue;
|
||||
item.val(parseInt(item.val()));
|
||||
var current = (check['port']||check['default']).toString();
|
||||
var userPort = (item.val()||check['default']).toString();
|
||||
if (userPort < 1 || userPort > 65535) range.push(userPort+' ('+check['name']+')');
|
||||
duplicates.push(userPort);
|
||||
if (check['used'] == '1' && userPort != current) {
|
||||
if (portsInUse.includes(parseInt(userPort))) list.push(userPort+' ('+check['name']+')');
|
||||
}
|
||||
}
|
||||
duplicates = duplicates.reduce(function(acc, el, i, arr) {
|
||||
if (arr.indexOf(el) !== i && acc.indexOf(el) < 0) acc.push(el); return acc;
|
||||
}, []);
|
||||
|
||||
if (range.length > 0) {
|
||||
swal({title:'_(Port out of range)_',text:sprintf('_(Port %s is out of range (minimum 1 maximum 65535))_',range.join(', ')),type:'error',showCancelButton:false,confirmButtonText:"_(OK)_"});
|
||||
return;
|
||||
}
|
||||
if (list.length > 0) {
|
||||
swal({title:'_(Port already in use)_',text:sprintf('_(Port %s is already in use by other services)_',list.join(', ')),type:'error',showCancelButton:false,confirmButtonText:"_(OK)_"});
|
||||
return;
|
||||
}
|
||||
if (duplicates.length > 0) {
|
||||
swal({title:'_(Duplicate port entered)_',text:sprintf('_(Port %s is duplicated)_',duplicates.join(', ')),type:'error',showCancelButton:false,confirmButtonText:"_(OK)_"});
|
||||
return;
|
||||
}
|
||||
form.submit();
|
||||
}
|
||||
|
||||
function updateTELNET(form) {
|
||||
form.PORTTELNET.disabled = form.USE_TELNET.value=='no';
|
||||
}
|
||||
|
||||
function updateSSH(form) {
|
||||
form.PORTSSH.disabled = form.USE_SSH.value=='no';
|
||||
}
|
||||
|
||||
|
||||
$(function(){
|
||||
var form = document.SSLSettings;
|
||||
updateTELNET(form);
|
||||
updateSSH(form);
|
||||
});
|
||||
</script>
|
||||
<form markdown="1" name="SSLSettings" method="POST" action="/update.htm" target="progressFrame">
|
||||
<input type="hidden" name="changePorts" value="Apply">
|
||||
<input type="hidden" name="server_name" value="<?=strtok(_var($_SERVER,'HTTP_HOST'),":")?>">
|
||||
<input type="hidden" name="server_addr" value="<?=_var($_SERVER,'SERVER_ADDR')?>">
|
||||
_(User 'root')_:
|
||||
: [_(Manage)_](/Settings/Users/ManagementAccess/UserEdit?name=root)
|
||||
|
||||
_(Start page)_:
|
||||
: <select name="START_PAGE">
|
||||
<?foreach ($tasks as $task) echo mk_option(_var($var,'START_PAGE','Main'), $task, _($task));?>
|
||||
</select>
|
||||
|
||||
:mgmt_start_page_help:
|
||||
|
||||
<!--
|
||||
Restrict access:
|
||||
: <select name="BIND_MGT" class="narrow">
|
||||
<?=mk_option($var['BIND_MGT'], "no", _('No'))?>
|
||||
<?=mk_option($var['BIND_MGT'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
> By default GUI, SSH and TELNET access are available on all active interfaces of the system.
|
||||
>
|
||||
> *Restrict access* limits GUI, SSH and TELNET access to the management interface only (eth0).
|
||||
-->
|
||||
|
||||
_(Use TELNET)_:
|
||||
: <select name="USE_TELNET" onchange="updateTELNET(this.form)">
|
||||
<?=mk_option($var['USE_TELNET'], "no", _('No'))?>
|
||||
<?=mk_option($var['USE_TELNET'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:mgmt_use_telnet_help:
|
||||
|
||||
_(TELNET port)_:
|
||||
: <input type="number" name="PORTTELNET" class="narrow" min="1" max="65535" value="<?=$var['PORTTELNET']?>" placeholder="23">
|
||||
|
||||
:mgmt_telnet_port_help:
|
||||
|
||||
_(Use SSH)_:
|
||||
: <select name="USE_SSH" onchange="updateSSH(this.form)">
|
||||
<?=mk_option($var['USE_SSH'], "no", _('No'))?>
|
||||
<?=mk_option($var['USE_SSH'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:mgmt_use_ssh_help:
|
||||
|
||||
_(SSH port)_:
|
||||
: <input type="number" name="PORTSSH" class="narrow" min="1" max="65535" value="<?=$var['PORTSSH']?>" placeholder="22">
|
||||
|
||||
:mgmt_ssh_port_help:
|
||||
|
||||
_(Use UPnP)_:
|
||||
: <select name="USE_UPNP">
|
||||
<?=mk_option($var['USE_UPNP'], "yes", _('Yes'))?>
|
||||
<?=mk_option($var['USE_UPNP'], "no", _('No'))?>
|
||||
</select>
|
||||
|
||||
:mgmt_use_upnp_help:
|
||||
|
||||
_(Use SSL/TLS)_:
|
||||
: <select name="USE_SSL" onchange="$('#ssl-warning').show();">
|
||||
<?=mk_option($var['USE_SSL'], "no", _('No'))?>
|
||||
<?=mk_option($var['USE_SSL'], "yes", _('Yes'))?>
|
||||
<?=mk_option($var['USE_SSL'], "auto", _('Strict'), $disabled_auto)?>
|
||||
</select><span id="ssl-warning" class="warning" style="display:none"><i class="fa fa-warning fa-fw"></i> _(if you have trouble logging in, close all other tabs pointing to this server and clear your browser's cache)_</span>
|
||||
|
||||
:mgmt_use_ssl_tls_help:
|
||||
|
||||
_(HTTP port)_:
|
||||
: <input type="number" name="PORT" class="narrow" min="1" max="65535" value="<?=$var['PORT']?>" placeholder="80">
|
||||
|
||||
:mgmt_http_port_help:
|
||||
|
||||
_(HTTPS port)_:
|
||||
: <input type="number" name="PORTSSL" class="narrow" min="1" max="65535" value="<?=$var['PORTSSL']?>" placeholder="443">
|
||||
|
||||
:mgmt_https_port_help:
|
||||
|
||||
_(Local TLD)_:
|
||||
: <input type="text" name="LOCAL_TLD" class="narrow" value="<?=htmlspecialchars($var['LOCAL_TLD'])?>">
|
||||
|
||||
:mgmt_local_tld_help:
|
||||
|
||||
|
||||
: <input type="button" value="_(Apply)_" onclick="checkPorts(this.form)" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
|
||||
</form>
|
||||
|
||||
_(Local access URLs)_:
|
||||
: <?
|
||||
// url[0] = url
|
||||
// url[1] = redirect url or null
|
||||
// url[2] = certificate used or null
|
||||
// url[3] = is certificate self-signed T/F
|
||||
$n = 0;
|
||||
foreach($urls as $url) {
|
||||
$msg = "";
|
||||
$url0 = substr_count($url[0]??'',':')>3 ? preg_replace('#(://)(.+?)(:?\d*)/$#','$1[$2]$3/',$url[0]) : $url[0]; // IPv6 - IPv4 notation
|
||||
$url1 = substr_count($url[1]??'',':')>3 ? preg_replace('#(://)(.+?)(:?\d*)/$#','$1[$2]$3/',$url[1]) : $url[1]; // IPv6 - IPv4 notation
|
||||
if ($url[1]) $msg .= " "._("redirects to")." <a href='$url1'>$url1</a>";
|
||||
if ($url[2]) $msg .= " "._("uses")." ".$url[2];
|
||||
if ($url[3]) $msg .= "<span class='warning'> <i class='fa fa-warning fa-fw'></i> "._("is a self-signed certificate, ignore the browser's warning and proceed to the GUI")."</span>";
|
||||
echo ($n ? "<dt> </dt><dd>" : ""),"<a href='$url0'>$url0</a>$msg",($n++ ? "</dd>" : "");
|
||||
}?>
|
||||
|
||||
:mgmt_local_access_urls_help:
|
||||
|
||||
<?if ($cert1Present):?>
|
||||
_(Self-signed or user-provided certificate)_:
|
||||
: <?=$cert1File?>
|
||||
|
||||
<?if ($cert1URLvalid && _var($var,'USE_SSL')=='yes'):?>
|
||||
_(Certificate URL)_:
|
||||
: <?="<a href='https://$cert1URL$https_port'>$cert1URL</a>"?>
|
||||
|
||||
<?elseif ($cert1URLvalid):?>
|
||||
_(Certificate URL)_:
|
||||
: <?=$cert1URL?>
|
||||
|
||||
<?else:?>
|
||||
_(Certificate URL)_:
|
||||
: _(Certificate not valid for)_ <?=$cert1URL?>
|
||||
<?endif;?>
|
||||
|
||||
_(Certificate issuer)_:
|
||||
: <?=$cert1Issuer?>
|
||||
<?if ($cert1URLvalid && _var($var,'USE_SSL')=='yes' && $cert1SelfSigned):?>
|
||||
<span class="warning"><i class="fa fa-warning fa-fw"></i> _(is a self-signed certificate, ignore the browser's warning when using this certificate)_</span>
|
||||
<?endif;?>
|
||||
|
||||
_(Certificate expiration)_:
|
||||
: <?=_(my_date($cert_time_format, strtotime($cert1Expires)),0)?>
|
||||
|
||||
<?else:?>
|
||||
_(Self-signed certificate file)_:
|
||||
: _(Not present)_
|
||||
<?endif;?>
|
||||
|
||||
<form markdown="1" name="Provision" method="POST" target="progressFrame" action="/update.htm" onsubmit="provisionHandler(event, this)">
|
||||
<input type="hidden" name="server_name" value="<?=strtok(_var($_SERVER,'HTTP_HOST'),":")?>">
|
||||
<input type="hidden" name="server_addr" value="<?=_var($_SERVER,'SERVER_ADDR')?>">
|
||||
<?if ($cert2Present):?>
|
||||
_(Unraid Let's Encrypt certificate)_:
|
||||
: <?=$cert2File?>
|
||||
|
||||
_(Certificate URL)_:
|
||||
: <?="<a href='https://$subject2URL$https_port'>$cert2Subject</a>"?>
|
||||
|
||||
_(Certificate issuer)_:
|
||||
: <?=$cert2Issuer?>
|
||||
|
||||
_(Certificate expiration)_:
|
||||
: <?=_(my_date($cert_time_format, strtotime($cert2Expires)),0)?>
|
||||
|
||||
<?if ($dnsRebindingProtection):?>
|
||||
|
||||
: _(DNS Rebinding Protection is ENABLED)_
|
||||
|
||||
<?elseif ($dnsValid !== true):?>
|
||||
|
||||
: _(DNS Propagation is PENDING)_
|
||||
|
||||
<?endif;?>
|
||||
<?else:?>
|
||||
_(CA-signed certificate file)_:
|
||||
: _(Not present)_
|
||||
|
||||
<?endif;?>
|
||||
|
||||
: <button type="submit" name="changePorts" value="Provision" <?=$disabled_provision?>><?=$provisionlabel?></button><button type="submit" name="changePorts" value="Delete" <?=$disabled_delete?> >_(Delete)_</button><!-- <button type="button" onclick="updateDNS(this)" <?=$disabled_updatedns?>>_(Update DNS)_</button> --><?=$disabled_provision_msg?>
|
||||
|
||||
<?if ($cert2Present && $isLegacyCert):?>
|
||||
|
||||
: <button type="submit" name="changePorts" value="Upgrade" <?=$disabled_upgrade?>><?=$upgradelabel?></button>
|
||||
<?endif;?>
|
||||
|
||||
:mgmt_certificate_expiration_help:
|
||||
|
||||
</form>
|
||||
@@ -0,0 +1,133 @@
|
||||
Menu="Scheduler:2"
|
||||
Title="Mover Settings"
|
||||
Tag="calendar-check-o"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$setup = true;
|
||||
if (!$pool_devices) {
|
||||
echo "<p class='notice'>"._('No Cache device present')."!</p>";
|
||||
$setup = false;
|
||||
} elseif ($var['shareUser']=='-') {
|
||||
echo "<p class='notice'>"._('User shares not enabled')."!</p>";
|
||||
$setup = false;
|
||||
}
|
||||
$cron = explode(' ',$var['shareMoverSchedule']);
|
||||
$move = $cron[2]!='*' ? 3 : ($cron[4]!='*' ? 2 : (substr($cron[1],0,1)!='*' ? 1 : 0));
|
||||
$mode = ['Hourly','Daily','Weekly','Monthly'];
|
||||
$days = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
|
||||
?>
|
||||
<script>
|
||||
<? if ($setup == true):?>
|
||||
$(function() {
|
||||
presetMover(document.mover_schedule);
|
||||
});
|
||||
<? endif; ?>
|
||||
// Fool Unraid by simulating the original input field
|
||||
function prepareMover(form) {
|
||||
var mode = form.shareMoverSchedule.value;
|
||||
var min = mode!=0 ? form.min.value : 0;
|
||||
var hour = mode!=0 ? form.hour1.value : form.hour2.value;
|
||||
form.shareMoverSchedule.options[mode].value = min+' '+hour+' '+form.dotm.value+' * '+form.day.value;
|
||||
form.min.disabled = true;
|
||||
form.hour1.disabled = true;
|
||||
form.hour2.disabled = true;
|
||||
form.dotm.disabled = true;
|
||||
form.day.disabled = true;
|
||||
}
|
||||
function presetMover(form) {
|
||||
var mode = form.shareMoverSchedule.value;
|
||||
form.min.disabled = false;
|
||||
form.day.disabled = mode!=2;
|
||||
form.dotm.disabled = mode!=3;
|
||||
form.day.value = form.day.disabled ? '*' : (form.day.value=='*' ? 0 : form.day.value);
|
||||
form.dotm.value = form.dotm.disabled ? '*' : (form.dotm.value=='*' ? 1 : form.dotm.value);
|
||||
if (mode==0) {$('#H1').hide(); $('#H2').show();} else {$('#H2').hide(); $('#H1').show();}
|
||||
}
|
||||
</script>
|
||||
<form markdown="1" name="mover_schedule" method="POST" action="/update.htm" target="progressFrame" onsubmit="prepareMover(this)">
|
||||
<?if ($setup):?>
|
||||
_(Mover schedule)_:
|
||||
: <select name="shareMoverSchedule" onchange="presetMover(this.form)">
|
||||
<?for ($m=0; $m<count($mode); $m++):?>
|
||||
<?=mk_option($move, strval($m), _($mode[$m]))?>
|
||||
<?endfor;?>
|
||||
</select>
|
||||
|
||||
:mover_schedule_help:
|
||||
|
||||
_(Day of the week)_:
|
||||
: <select name="day">
|
||||
<?for ($d=0; $d<count($days); $d++):?>
|
||||
<?=mk_option($cron[4], strval($d), _($days[$d],0))?>
|
||||
<?endfor;?>
|
||||
<?=mk_option($cron[4], "*", "--------", "disabled")?>
|
||||
</select>
|
||||
|
||||
:mover_day_of_the_week_help:
|
||||
|
||||
_(Day of the month)_:
|
||||
: <select name="dotm">
|
||||
<?for ($d=1; $d<=31; $d++):?>
|
||||
<?=mk_option($cron[2], strval($d), sprintf("%02d", $d))?>
|
||||
<?endfor;?>
|
||||
<?=mk_option($cron[2], "*", "--------", "disabled")?>
|
||||
</select>
|
||||
|
||||
:mover_day_of_the_month_help:
|
||||
|
||||
_(Time of the day)_:
|
||||
: <span id="H1"<?if ($move==0):?> style="display:none"<?endif;?>><select name="hour1" class="narrow">
|
||||
<?for ($d=0; $d<=23; $d++):?>
|
||||
<?=mk_option($cron[1], strval($d), sprintf("%02d", $d))?>
|
||||
<?endfor;?>
|
||||
</select>
|
||||
<select name="min" class="narrow">
|
||||
<?for ($d=0; $d<=55; $d+=5):?>
|
||||
<?=mk_option($cron[0], strval($d), sprintf("%02d", $d))?>
|
||||
<?endfor;?>
|
||||
</select> _(HH:MM)_</span>
|
||||
: <span id="H2"<?if ($move!=0):?> style="display:none"<?endif;?>><select name="hour2">
|
||||
<?=mk_option($cron[1], "*/1", _("Every hour"))?>
|
||||
<?=mk_option($cron[1], "*/2", _("Every 2 hours"))?>
|
||||
<?=mk_option($cron[1], "*/3", _("Every 3 hours"))?>
|
||||
<?=mk_option($cron[1], "*/4", _("Every 4 hours"))?>
|
||||
<?=mk_option($cron[1], "*/6", _("Every 6 hours"))?>
|
||||
<?=mk_option($cron[1], "*/8", _("Every 8 hours"))?>
|
||||
</select></span>
|
||||
|
||||
:mover_time_of_the_day_help:
|
||||
|
||||
_(Mover logging)_:
|
||||
: <select name="shareMoverLogging">
|
||||
<?=mk_option($var['shareMoverLogging'], "yes", _("Enabled"))?>
|
||||
<?=mk_option($var['shareMoverLogging'], "no", _("Disabled"))?>
|
||||
</select>
|
||||
|
||||
:mover_logging_help:
|
||||
|
||||
<?endif;?>
|
||||
<?if ($setup):?>
|
||||
<?if ($pool_devices):?>
|
||||
<?if (file_exists('/var/run/mover.pid')):?>
|
||||
<input type="submit" name="cmdStartMover" value="_(Move now)_" disabled> _(Mover is running)_
|
||||
<?else:?>
|
||||
<input type="submit" name="cmdStartMover" value="_(Move now)_"> _(Click to invoke the Mover)_
|
||||
<?endif;?>
|
||||
<?else:?>
|
||||
|
||||
<?endif;?>
|
||||
: <input type="submit" name="changeMover" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
<?endif;?>
|
||||
</form>
|
||||
@@ -0,0 +1,42 @@
|
||||
Menu="NetworkServices:2"
|
||||
Title="NFS"
|
||||
Icon="icon-linux"
|
||||
Tag="linux"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
function checkNFSenable() {
|
||||
var form = document.nfs_enable;
|
||||
form.fuse_remember.disabled = form.shareNFSEnabled.value=="_(no)_";
|
||||
}
|
||||
$(checkNFSenable);
|
||||
</script>
|
||||
|
||||
<form markdown="1" name="nfs_enable" method="POST" action="/update.htm" target="progressFrame">
|
||||
_(Enable NFS)_:
|
||||
: <select name="shareNFSEnabled" onchange="checkNFSenable()">
|
||||
<?=mk_option($var['shareNFSEnabled'], "no", _('No'));?>
|
||||
<?=mk_option($var['shareNFSEnabled'], "yes", _('Yes'));?>
|
||||
</select>
|
||||
|
||||
:nfs_enable_help:
|
||||
|
||||
_(Tunable (fuse_remember))_:
|
||||
: <input type="text" name="fuse_remember" maxlength="10" value="<?=$var['fuse_remember']?>" class="narrow"><?=_($var['fuse_remember_status'])?>
|
||||
|
||||
:nfs_tunable_fuse_remember_help:
|
||||
|
||||
|
||||
: <input type="submit" name="changeShare" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
@@ -0,0 +1,116 @@
|
||||
Menu="NetworkSettings"
|
||||
Title="Interface Extra"
|
||||
Tag="icon-ethernet"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2023, Lime Technology
|
||||
* Copyright 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$cfg = '/boot/config/network-extra.cfg';
|
||||
|
||||
if (file_exists($cfg)) {
|
||||
extract(parse_ini_file($cfg));
|
||||
$include_interfaces = str_replace(" ","\n",$include_interfaces);
|
||||
$exclude_interfaces = str_replace(" ","\n",$exclude_interfaces);
|
||||
} else {
|
||||
$include_interfaces = "";
|
||||
$exclude_interfaces = "";
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
span[id^="info-"]{margin-left:20px}
|
||||
<?if ($themes1):?>
|
||||
span.status.vhshift{margin-right:-10px!important}
|
||||
<?endif;?>
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function prepareText(form) {
|
||||
var mgmt = ['br0','bond0','eth0'];
|
||||
form.include_interfaces.value = form.include.value.replace(/[\n,]/g,' ').replace(/ +/g,' ').trim();
|
||||
form.exclude_interfaces.value = form.exclude.value.replace(/[\n,]/g,' ').replace(/ +/g,' ').trim();
|
||||
form.include.disabled = true;
|
||||
form.exclude.disabled = true;
|
||||
var include = form.include_interfaces.value.split(' ');
|
||||
var exclude = form.exclude_interfaces.value.split(' ');
|
||||
// silently remove management interfaces from include list
|
||||
for (var i=0,name; name=include[i]; i++) {
|
||||
if (mgmt.includes(name)) include[i] = '';
|
||||
}
|
||||
form.include_interfaces.value = include.join(' ').replace(/ +/g,' ').trim();
|
||||
// give warning when management interface is excluded
|
||||
for (var i=0,name; name=exclude[i]; i++) {
|
||||
if (mgmt.includes(name)) {
|
||||
swal({title:"_(Management Interface)_ '"+name+"'",text:"_(You can not exclude this interface)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
|
||||
form.include.disabled = false;
|
||||
form.exclude.disabled = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
<?if (!$tabbed):?>
|
||||
function toggleExtra() {
|
||||
var tag = '#tag_extra';
|
||||
var view = '#extra_table';
|
||||
if ($(view).is(':visible')) {
|
||||
$(tag).removeClass('fa-chevron-up').addClass('fa-chevron-down');
|
||||
$.cookie(view,'hide',{expires:3650});
|
||||
} else {
|
||||
$(tag).removeClass('fa-chevron-down').addClass('fa-chevron-up');
|
||||
$.removeCookie(view);
|
||||
}
|
||||
$(view).toggle('slow');
|
||||
}
|
||||
$(function(){
|
||||
$('div.title').eq(-3).find('span.left').append("<span class='status vhshift'><i id='tag_extra' class='fa fa-fw fa-chevron-up' style='cursor:pointer' onclick='toggleExtra()'></i></span>");
|
||||
if (!$.cookie('#extra_table')) $('#extra_table').show(); else {$('#extra_table').hide(); $('#tag_extra').removeClass('fa-chevron-up').addClass('fa-chevron-down');}
|
||||
});
|
||||
<?else:?>
|
||||
$(function(){
|
||||
$('#extra_table').show();
|
||||
});
|
||||
<?endif;?>
|
||||
$(function(){
|
||||
$('form textarea').on('input',function(){
|
||||
$(this).prop('rows',($(this).val().match(/\n/g)||[]).length+1);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div markdown="1" id="extra_table" style="display:none">
|
||||
<form markdown="1" name="network_extra" method="POST" action="/update.php" target="progressFrame" onsubmit="return prepareText(this)">
|
||||
<input type="hidden" name="#file" value="<?=$cfg?>">
|
||||
<input type="hidden" name="#command" value="/webGui/scripts/reload_services">
|
||||
<input type="hidden" name="include_interfaces" value="">
|
||||
<input type="hidden" name="exclude_interfaces" value="">
|
||||
|
||||
_(Current listening interfaces)_:
|
||||
: <?=exec("$docroot/webGui/scripts/show_interfaces")?:_('Any')?>
|
||||
<hr>
|
||||
|
||||
_(Include listening interfaces)_:
|
||||
: <textarea name="include" spellcheck="false" cols="80" rows="<?=substr_count($include_interfaces,"\n")+1?>" maxlength="2048" name="text" style="resize:none;width:200px"><?=$include_interfaces?></textarea>
|
||||
|
||||
:eth_network_extra_include_help:
|
||||
|
||||
_(Exclude listening interfaces)_:
|
||||
: <textarea name="exclude" spellcheck="false" cols="80" rows="<?=substr_count($exclude_interfaces,"\n")+1?>" maxlength="2048" name="text" style="resize:none;width:200px"><?=$exclude_interfaces?></textarea>
|
||||
|
||||
:eth_network_extra_exclude_help:
|
||||
|
||||
|
||||
: <input type="submit" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,110 @@
|
||||
Menu="NetworkSettings"
|
||||
Title="Interface Rules"
|
||||
Tag="icon-network"
|
||||
Cond="file_exists('/boot/config/network-rules.cfg')"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2023, Lime Technology
|
||||
* Copyright 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$cfg = '/boot/config/network-rules.cfg';
|
||||
|
||||
function strip($item) {
|
||||
[$key,$val] = explode('"',$item);
|
||||
return $val;
|
||||
}
|
||||
|
||||
exec("awk '/NAME=\"eth/{print $4 $8}' $cfg",$rules);
|
||||
exec("grep -Po '^# \K.*' $cfg",$info);
|
||||
|
||||
$link = []; $i = 0;
|
||||
foreach ($rules as $rule) {
|
||||
[$mac,$eth] = array_map('strip',my_explode(',',$rule));
|
||||
$link[$eth]['mac'] = $mac;
|
||||
$link[$eth]['info'] = $info[$i++];
|
||||
}
|
||||
ksort($link,SORT_NATURAL);
|
||||
?>
|
||||
<style>
|
||||
span[id^="info-"]{margin-left:20px}
|
||||
<?if ($themes1):?>
|
||||
span.status.vhshift{margin-right:-10px!important}
|
||||
<?endif;?>
|
||||
</style>
|
||||
<script>
|
||||
var info = {};
|
||||
<?foreach ($link as $eth => $val):?>
|
||||
info['<?='_'.str_replace(':','',$val['mac'])?>'] = "<?=$val['info']?>";
|
||||
<?endforeach;?>
|
||||
|
||||
function check_rules(form) {
|
||||
var mac = [];
|
||||
$(form).find('select[name^="eth"]').each(function(){mac.push($(this).val());});
|
||||
if (mac.same()) {
|
||||
swal({title:"_(MAC address mismatch)_",text:"_(Rules contain duplicate MAC address assignments)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
function update_info(id,mac) {
|
||||
$('#info-'+id).html(info['_'+mac.replace(/:/g,'')]);
|
||||
}
|
||||
<?if (!$tabbed):?>
|
||||
function toggleRules() {
|
||||
var tag = '#tag_rules';
|
||||
var view = '#rules_table';
|
||||
if ($(view).is(':visible')) {
|
||||
$(tag).removeClass('fa-chevron-up').addClass('fa-chevron-down');
|
||||
$.cookie(view,'hide',{expires:3650});
|
||||
} else {
|
||||
$(tag).removeClass('fa-chevron-down').addClass('fa-chevron-up');
|
||||
$.removeCookie(view);
|
||||
}
|
||||
$(view).toggle('slow');
|
||||
}
|
||||
$(function(){
|
||||
$('div.title').eq(-2).find('span.left').append("<span class='status vhshift'><i id='tag_rules' class='fa fa-fw fa-chevron-up' style='cursor:pointer' onclick='toggleRules()'></i></span>");
|
||||
if (!$.cookie('#rules_table')) $('#rules_table').show(); else {$('#rules_table').hide(); $('#tag_rules').removeClass('fa-chevron-up').addClass('fa-chevron-down');}
|
||||
});
|
||||
<?else:?>
|
||||
$(function(){
|
||||
$('#rules_table').show();
|
||||
});
|
||||
<?endif;?>
|
||||
</script>
|
||||
<div markdown="1" id="rules_table" style="display:none">
|
||||
<form markdown="1" name="network_rules" method="POST" action="/update.php" target="progressFrame" onsubmit="return check_rules(this)">
|
||||
<input type="hidden" name="#file" value="not-used">
|
||||
<input type="hidden" name="#include" value="/webGui/include/update.rules.php">
|
||||
<input type="hidden" name="#cfg" value="<?=$cfg?>">
|
||||
<?foreach ($link as $eth => $file):?>
|
||||
|
||||
_(Interface)_ <?=$eth?>:
|
||||
: <select name="<?=$eth?>" onchange="update_info(this.name,this.value)">
|
||||
<?foreach ($link as $my => $val):?>
|
||||
<?=mk_option($file['mac'],$val['mac'],strtoupper($val['mac']));?>
|
||||
<?endforeach;?>
|
||||
</select><span id="info-<?=$eth?>"><?=$file['info']?></span>
|
||||
|
||||
<?endforeach;?>
|
||||
|
||||
|
||||
: <input type="submit" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
|
||||
:eth_network_rules_help:
|
||||
|
||||
<?if (file_exists('/tmp/network-rules.tmp')):?>
|
||||
<br><span class="error" style="text-align:center;padding:12px 0">_(Please **Reboot** system to make new rules active)_</span>
|
||||
<?endif;?>
|
||||
</div>
|
||||
@@ -0,0 +1,4 @@
|
||||
Menu="Settings:2"
|
||||
Type="menu"
|
||||
Title="Network Services"
|
||||
Tag="globe"
|
||||
@@ -0,0 +1,4 @@
|
||||
Menu="OtherSettings"
|
||||
Type="xmenu"
|
||||
Title="Network Settings"
|
||||
Icon="icon-network"
|
||||
@@ -0,0 +1,2 @@
|
||||
Type="xmenu"
|
||||
Tabs="true"
|
||||
@@ -0,0 +1,84 @@
|
||||
Menu="UNRAID-OS"
|
||||
Title="New Config"
|
||||
Icon="icon-config"
|
||||
Tag="cog"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$newarray = $var['mdState']=='NEW_ARRAY';
|
||||
$disabled = $var['fsState']=="Started";
|
||||
$width = [166,300];
|
||||
if ($newarray) {
|
||||
@unlink('/boot/config/smart-one.cfg');
|
||||
@unlink('/boot/config/smart-all.cfg');
|
||||
@unlink('/boot/config/plugins/dynamix/monitor.ini');
|
||||
foreach ($pools as $pool) @unlink("/var/tmp/$pool.log.tmp");
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
span.indent{display:inline-block;width:240px;margin-top:30px}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function prepareNewConfig(form) {
|
||||
for (var i=1,item; item=form.preset.options[i]; i++) {
|
||||
switch (item.value) {
|
||||
case 'array': if (item.selected) form.preserveArray.disabled = false; break;
|
||||
case 'cache' : if (item.selected) form.preserveCache.disabled = false; break;
|
||||
}
|
||||
}
|
||||
form.preset.disabled = true;
|
||||
}
|
||||
$(function() {
|
||||
$('#s1').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[0]?>, firstItemChecksAll:true, explicitClose:"..._(close)_"});
|
||||
<?if ($disabled):?>
|
||||
$('#s1').dropdownchecklist('disable');
|
||||
<?endif;?>
|
||||
});
|
||||
</script>
|
||||
|
||||
:newconfig_plug:
|
||||
This is a utility to reset the array disk configuration so that all disks appear as "New" disks, as
|
||||
if it were a fresh new server.
|
||||
|
||||
This is useful when you have added or removed multiple drives and wish to rebuild parity based on
|
||||
the new configuration.
|
||||
|
||||
Use the *'Preserve current assignments'* selection to populate the desired disk slots ***after*** the array has been reset. By default **no** disk slots are populated.
|
||||
|
||||
**DO NOT USE THIS UTILITY THINKING IT WILL REBUILD A FAILED DRIVE** - it will have the opposite
|
||||
effect of making it ***impossible*** to rebuild an existing failed drive - you have been warned!
|
||||
:end
|
||||
|
||||
<hr>
|
||||
<form name="newConfig" method="POST" action="/update.htm" target="progressFrame" onsubmit="prepareNewConfig(this)">
|
||||
<input type="hidden" name="preserveArray" value="yes" disabled>
|
||||
<input type="hidden" name="preserveCache" value="yes" disabled>
|
||||
|
||||
<span class="indent">_(Preserve current assignments)_:</span>
|
||||
<select id="s1" name="preset" multiple="multiple" style="display:none">
|
||||
<option value=''>_(All)_</option>
|
||||
<?=mk_option_check(0,'array',_('Array slots'))?>
|
||||
<?=mk_option_check(0,'cache',_('Pool slots'))?>
|
||||
</select>
|
||||
<br>
|
||||
<span class="indent"><input type="submit" class="lock" name="cmdInit" value="_(Apply)_" disabled><input type="button" class="lock" value="_(Done)_" onclick="done()"></span>
|
||||
<?if ($newarray):?>
|
||||
_(Array has been **Reset**)_ (_(please configure)_)
|
||||
<?elseif ($disabled):?>
|
||||
_(Array must be **Stopped** to change)_
|
||||
<?else:?>
|
||||
<input type="checkbox" onClick="cmdInit.disabled=!this.checked"><small>_(Yes, I want to do this)_</small>
|
||||
<?endif;?>
|
||||
</form>
|
||||
@@ -0,0 +1,133 @@
|
||||
Menu="UNRAID-OS"
|
||||
Title="New Permissions"
|
||||
Icon="icon-permissions"
|
||||
Tag="folder-o"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$width = [166,300];
|
||||
function data_disks($disk) {
|
||||
global $pools;
|
||||
return (_var($disk,'type')=="Data" || (_var($disk,'type')=="Cache" && in_array(_var($disk,'name'),$pools))) && _var($disk,'status')=='DISK_OK';
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
span.block{display:inline-block;width:300px;margin:24px 0}
|
||||
pre.pre{margin:30px 0;padding:20px}
|
||||
pre>p{margin:0;padding:0}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function selection(select,remove) {
|
||||
if (remove) {
|
||||
$('#s1').dropdownchecklist('destroy');
|
||||
$('#s2').dropdownchecklist('destroy');
|
||||
}
|
||||
if (select==0) {$('#disks').show(); $('#shares').hide();} else {$('#shares').show(); $('#disks').hide();}
|
||||
$('#s1').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[0]?>, firstItemChecksAll:true, explicitClose:"..._(close)_"});
|
||||
$('#s2').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[0]?>, firstItemChecksAll:true, explicitClose:"..._(close)_"});
|
||||
<?if ($var['fsState']!="Started"):?>
|
||||
$('#s1').dropdownchecklist('disable');
|
||||
$('#s2').dropdownchecklist('disable');
|
||||
<?endif;?>
|
||||
}
|
||||
function setNewPerms(form) {
|
||||
var dirs = [];
|
||||
if (form.select.value==0) {
|
||||
for (var i=1,item; item=form.disks.options[i]; i++) {
|
||||
if (item.selected) dirs.push(item.value);
|
||||
}
|
||||
} else {
|
||||
for (var i=1,item; item=form.shares.options[i]; i++) {
|
||||
if (item.selected) dirs.push(item.value);
|
||||
}
|
||||
}
|
||||
dirs = dirs.join('*');
|
||||
if (dirs) {
|
||||
swal({title:"_(Proceed)_?",text:"_(This will update folder & file permissions)_",type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},
|
||||
function(){setTimeout(function(){openPlugin('newperms '+encodeURIComponent(dirs),"_(New Permissions)_");},250);
|
||||
});
|
||||
}
|
||||
}
|
||||
$(function() {
|
||||
selection(0,false);
|
||||
});
|
||||
</script>
|
||||
|
||||
:newperms_1_plug:
|
||||
This is a mandatory one-time action to be taken after upgrading from a pre-5.0 Unraid server release to Unraid v5 or a later release.
|
||||
Select **ALL DISKS** when performing this one-time action.
|
||||
|
||||
This utility is also useful for restoring default ownership/permissions on files and
|
||||
directories when transitioning back from Active Directory to non-Active Directory integration.
|
||||
|
||||
The utility starts a background process that goes to each of your data disks and cache disks and selected user shares
|
||||
and changes file and directory ownership to *nobody/users* (i.e., uid/gid to 99/100), and sets permissions
|
||||
as follows:
|
||||
:end
|
||||
|
||||
<pre class="pre">
|
||||
:newperms_2_plug:
|
||||
For directories:
|
||||
drwxrwxrwx
|
||||
|
||||
For read/write files:
|
||||
-rw-rw-rw-
|
||||
|
||||
For readonly files:
|
||||
-r--r--r--
|
||||
:end
|
||||
</pre>
|
||||
|
||||
:newperms_3_plug:
|
||||
Clicking **Start** will open another window and start the background process.
|
||||
|
||||
Closing the window before completion will terminate the background process - so don't do that. This process can take a long time if you have many files.
|
||||
|
||||
Note that this tool may negatively affect any docker containers if you allow your **appdata** share to be included.
|
||||
:end
|
||||
|
||||
<form method="POST" action="/update.htm" target="progressFrame">
|
||||
<span class="block">
|
||||
<select name="select" onchange="selection(this.value,true)">
|
||||
<?=mk_option(0,"0","_(Disks)_")?>
|
||||
<?=mk_option(0,"1","_(Shares)_")?>
|
||||
</select>
|
||||
</span>
|
||||
|
||||
<span id="disks" class="block">
|
||||
<select id="s1" name="disks" style="display:none" multiple>
|
||||
<option value=''>_(All)_</option>
|
||||
<?foreach (array_filter($disks,'data_disks') as $disk):?>
|
||||
<?=mk_option(1,"/mnt/{$disk['name']}",_(my_disk($disk['name'])),3)?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
</span>
|
||||
|
||||
<span id="shares" class="block" style="display:none">
|
||||
<select id="s2" name="shares" style="display:none" multiple>
|
||||
<option value=''>_(All)_</option>
|
||||
<?uksort($shares,'strnatcasecmp');?>
|
||||
<?foreach ($shares as $share):?>
|
||||
<?=mk_option(1,"/mnt/user/{$share['name']}",$share['name'])?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
</span>
|
||||
|
||||
<?if (_var($var,'fsState')=="Started"):?>
|
||||
<div><input type="button" value="_(Start)_" onclick="setNewPerms(this.form)"><input type="button" value="_(Done)_" class="lock" onclick="done()"></div>
|
||||
<?else:?>
|
||||
<div><input type="button" value="_(Start)_" disabled><input type="button" value="_(Done)_" class="lock" onclick="done()">_(Array must be **Started** to change permissions)_.</div>
|
||||
<?endif;?>
|
||||
</form>
|
||||
@@ -0,0 +1,159 @@
|
||||
Menu="Notifications:3"
|
||||
Title="Notification Agents"
|
||||
Tag="rss-square"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
var scripts = new Object();
|
||||
var enabledAgents = new Object();
|
||||
var disabledAgents = new Object();
|
||||
var openPage = true;
|
||||
|
||||
<?$width = [166,300]?>
|
||||
<?if ($tabbed):?>
|
||||
$('#tab3').bind({click:function(){initDropdown();}});
|
||||
$(function(){if ($('#tab3').is(':checked')) initDropdown();});
|
||||
<?else:?>
|
||||
$(function(){initDropdown();});
|
||||
<?endif;?>
|
||||
|
||||
if (!String.prototype.format) {
|
||||
String.prototype.format = function() {
|
||||
var args = arguments;
|
||||
return this.replace(/{(\d+)}/g, function(match, number) {
|
||||
return typeof args[number] != 'undefined' ? args[number] : match;
|
||||
});
|
||||
};
|
||||
}
|
||||
function addSlashes(text) {
|
||||
return text.replace(/\"/g, "\\\"");
|
||||
}
|
||||
function prepareService(el, name) {
|
||||
var script = scripts[name];
|
||||
var vars = "";
|
||||
var form = $(el).parents('form:first');
|
||||
form.find('.variable').each(function() {
|
||||
vars += $(this).attr('name')+'="'+addSlashes($(this).val())+"\"\n";
|
||||
});
|
||||
$('[name="'+name+'"] [id^="slot_"]').each(function() {
|
||||
var include = '';
|
||||
$(this).find('option').each(function() {
|
||||
if ($(this).is(':selected')) {
|
||||
if (include.length) include += '\\n';
|
||||
include += $(this).val();
|
||||
$(this).removeAttr('selected');
|
||||
}
|
||||
});
|
||||
vars += $(this).attr('name')+'="'+include+"\"\n";
|
||||
});
|
||||
var cmd = (form.find('select[name="Enabled"]').val()=='yes' ? 'enable' : 'disable');
|
||||
form.find('input[name="#arg\\[1\\]"]').val(cmd);
|
||||
form.find('input[name="#arg\\[2\\]"]').val(name+'.sh');
|
||||
form.find('input[name="text"]').val(script.format(vars,'\n'));
|
||||
}
|
||||
function execCmd(cmd, name) {
|
||||
var form = $('#formExec');
|
||||
form.find('input[name="#arg\\[1\\]"]').val(cmd);
|
||||
if (name) form.find('input[name="#arg\\[2\\]"]').val(name+'.sh');
|
||||
form.submit();
|
||||
}
|
||||
function testService(name) {
|
||||
var form = $('#formExec');
|
||||
form.find('input[name="#arg\\[1\\]"]').val('test');
|
||||
form.find('input[name="#arg\\[2\\]"]').val(name+'.sh');
|
||||
form.append('<input type="hidden" name="#env[]" value="EVENT='+name+' test.">');
|
||||
form.append('<input type="hidden" name="#env[]" value="SUBJECT='+name+' test.">');
|
||||
form.append('<input type="hidden" name="#env[]" value="DESCRIPTION='+name+' test.">');
|
||||
form.append('<input type="hidden" name="#env[]" value="IMPORTANCE=normal">');
|
||||
// host is normally added to link by the notify script. add it here since calling the agent directly.
|
||||
form.append('<input type="hidden" name="#env[]" value="LINK='+window.location.origin+'/Settings/Notifications">');
|
||||
form.submit();
|
||||
}
|
||||
function initDropdown() {
|
||||
if (openPage) {$("[id^='slot_']").dropdownchecklist({width:<?=$width[1]?>,explicitClose:'..._(close)_'}); openPage = false;}
|
||||
}
|
||||
</script>
|
||||
<form method="POST" id="formExec" action="/update.php" target="progressFrame">
|
||||
<input type="hidden" name="#command" value="/webGui/scripts/agent">
|
||||
<input type="hidden" name="#arg[1]" value="">
|
||||
<input type="hidden" name="#arg[2]" value="">
|
||||
</form>
|
||||
<?
|
||||
$fields = ['Event','Subject','Timestamp','Description','Importance','Content','Link'];
|
||||
$xml_file = "webGui/include/NotificationAgents.xml";
|
||||
$xml = @simplexml_load_file($xml_file) or die(_("Failed to open")." $xml_file");
|
||||
$i = 1;
|
||||
foreach ($xml->Agent as $agent) {
|
||||
$name = str_replace(' ','_',$agent->Name);
|
||||
$enabledAgent = agent_fullname("$name.sh", "enabled");
|
||||
$disabledAgent = agent_fullname("$name.sh", "disabled");
|
||||
if (is_file($disabledAgent)) {
|
||||
$file = $disabledAgent;
|
||||
if (is_file($enabledAgent)) unlink($enabledAgent);
|
||||
} else {
|
||||
$file = $enabledAgent;
|
||||
}
|
||||
$values = [];
|
||||
$script = "";
|
||||
if (is_file($file)) {
|
||||
preg_match("/[#]{6,100}([^#]*?)[#]{6,100}/si", file_get_contents($file), $match);
|
||||
if (isset($match[1])) {
|
||||
foreach (explode(PHP_EOL, $match[1]) as $line) {
|
||||
if (strpos($line, "=")) {
|
||||
[$k, $v] = my_explode("=",str_replace("\"", "", $line),2);
|
||||
$values[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (explode(PHP_EOL,(String) $agent->Script) as $line) if (trim($line)) $script .= trim($line)."{1}";
|
||||
echo '<div class="title shift"><span class="left"><img src="/plugins/dynamix/icons/'.strtolower(str_replace('_','',$name)).'.png" class="icon" style="height:16px;width:16px;">'.str_replace('_',' ',$name).'</span><span class="status vhshift">'.(is_file($enabledAgent) ? '<span class="green">'._("Enabled").'</span>' : '<span class="red">'._("Disabled").'</span>').'</span></div>';
|
||||
echo '<form method="POST" name="'.$name.'" action="/update.php" target="progressFrame">';
|
||||
echo '<input type="hidden" name="#include" value="/webGui/include/update.file.php">';
|
||||
echo '<input type="hidden" name="#file" value="'.$file.'">';
|
||||
echo '<input type="hidden" name="#command" value="/webGui/scripts/agent">';
|
||||
echo '<input type="hidden" name="#arg[1]" value="">';
|
||||
echo '<input type="hidden" name="#arg[2]" value="">';
|
||||
echo '<input type="hidden" name="text" value="">';
|
||||
echo '<dl><dt>'._("Agent function").':</dt><dd><select name="Enabled">';
|
||||
echo mk_option(is_file($disabledAgent), 'no', _('Disabled'));
|
||||
echo mk_option(is_file($enabledAgent), 'yes', _('Enabled'));
|
||||
echo '</select></dd></dl>';
|
||||
echo '<script>scripts["'.$name.'"]='.json_encode($script).';enabledAgents["'.$name.'"]="'.$enabledAgent.'";disabledAgents["'.$name.'"]="'.$disabledAgent.'";</script>';
|
||||
foreach ($agent->Variables->children() as $v) {
|
||||
$vName = preg_replace('#\[([^\]]*)\]#', '<$1>', (string) $v);
|
||||
$vDesc = ucfirst(strtolower(preg_replace('#\[([^\]]*)\]#', '<$1>', $v->attributes()->Desc)));
|
||||
$vDefault = preg_replace('#\[([^\]]*)\]#', '<$1>', $v->attributes()->Default);
|
||||
$vHelp = preg_replace('#\[([^\]]*)\]#', '<$1>', $v->attributes()->Help);
|
||||
echo "<dl><dt>$vDesc:</dt><dd>";
|
||||
if (preg_match('/title|message/', $vDesc)) {
|
||||
echo '<select id="slot_'.$i++.'" name="'.$vName.'" multiple style="display:none">';
|
||||
$value = str_replace('\n',',',isset($values[$vName]) ? $values[$vName] : $vDefault);
|
||||
foreach ($fields as $field) echo mk_option_check($value,'$'.strtoupper($field),_($field));
|
||||
echo '</select>';
|
||||
} else {
|
||||
echo '<input type="text" name="'.$vName.'" class="variable" required value="'.( isset($values[$vName]) ? $values[$vName] : $vDefault ).'">';
|
||||
}
|
||||
echo '</dd></dl>';
|
||||
if ($vHelp) echo '<blockquote class="inline_help">'.$vHelp.'</blockquote>';
|
||||
}
|
||||
echo '<dl><dt> </dt><dd><input type="submit" value='._("Apply").' onclick="prepareService(this, \''.$name.'\')" disabled>';
|
||||
echo '<input type="button" value='._("Done").' onclick="done()">';
|
||||
if (is_file($file)) {
|
||||
echo '<input type="button" value='._("Delete").' onclick="execCmd(\'delete\',\''.$name.'\')">';
|
||||
echo '<input type="button" value='._("Test").' onclick="testService(\''.$name.'\')"'.($file==$enabledAgent ? '>' : ' disabled>');
|
||||
}
|
||||
echo '</dd></dl></form><div style="min-height:50px;"></div>';
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,285 @@
|
||||
Menu="UserPreferences"
|
||||
Type="xmenu"
|
||||
Title="Notification Settings"
|
||||
Icon="icon-notifications"
|
||||
Tag="phone-square"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2012-2022, Bergware International.
|
||||
* Copyright 2012, Andrew Hamer-Adams, http://www.pixeleyes.co.nz.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$events = explode('|', $notify['events'] ?? '');
|
||||
$disabled = $notify['system'] ? '' : 'disabled';
|
||||
?>
|
||||
<style>
|
||||
select.a{min-width:220px}
|
||||
span.a{display:inline-block;width:220px;font-style:italic}
|
||||
</style>
|
||||
<script>
|
||||
function prepareNotify(form) {
|
||||
form.entity.value = form.normal1.checked | form.warning1.checked | form.alert1.checked;
|
||||
form.normal.value = form.normal1.checked*1 + form.normal2.checked*2 + form.normal3.checked*4;
|
||||
form.warning.value = form.warning1.checked*1 + form.warning2.checked*2 + form.warning3.checked*4;
|
||||
form.alert.value = form.alert1.checked*1 + form.alert2.checked*2 + form.alert3.checked*4;
|
||||
form.unraid.value = form.unraid1.checked*1 + form.unraid2.checked*2 + form.unraid3.checked*4;
|
||||
form.plugin.value = form.plugin1.checked*1 + form.plugin2.checked*2 + form.plugin3.checked*4;
|
||||
form.docker_notify.value = form.docker_notify1.checked*1 + form.docker_notify2.checked*2 + form.docker_notify3.checked*4;
|
||||
form.language_notify.value = form.language_notify1.checked*1 + form.language_notify2.checked*2 + form.language_notify3.checked*4;
|
||||
form.report.value = form.report1.checked*1 + form.report2.checked*2 + form.report3.checked*4;
|
||||
form.normal1.disabled = true;
|
||||
form.normal2.disabled = true;
|
||||
form.normal3.disabled = true;
|
||||
form.warning1.disabled = true;
|
||||
form.warning2.disabled = true;
|
||||
form.warning3.disabled = true;
|
||||
form.alert1.disabled = true;
|
||||
form.alert2.disabled = true;
|
||||
form.alert3.disabled = true;
|
||||
form.unraid1.disabled = true;
|
||||
form.unraid2.disabled = true;
|
||||
form.unraid3.disabled = true;
|
||||
form.plugin1.disabled = true;
|
||||
form.plugin2.disabled = true;
|
||||
form.plugin3.disabled = true;
|
||||
form.docker_notify1.disabled = true;
|
||||
form.docker_notify2.disabled = true;
|
||||
form.docker_notify3.disabled = true;
|
||||
form.language_notify1.disabled = true;
|
||||
form.language_notify2.disabled = true;
|
||||
form.language_notify3.disabled = true;
|
||||
form.report1.disabled = true;
|
||||
form.report2.disabled = true;
|
||||
form.report3.disabled = true;
|
||||
}
|
||||
function prepareSystem(index) {
|
||||
if (index==0) $('.checkbox').attr('disabled','disabled'); else $('.checkbox').removeAttr('disabled');
|
||||
}
|
||||
function prepareTitle() {
|
||||
var title = '_(Available notifications)_:';
|
||||
$('#unraidTitle,#pluginTitle,#dockerTitle,#languageTitle,#reportTitle').html(' ');
|
||||
if ($('.unraid').is(':visible')) {$('#unraidTitle').html(title); return;}
|
||||
if ($('.plugin').is(':visible')) {$('#pluginTitle').html(title); return;}
|
||||
if ($('.docker').is(':visible')) {$('#dockerTitle').html(title); return;}
|
||||
if ($('.language').is(':visible')) {$('#languageTitle').html(title); return;}
|
||||
if ($('.report').is(':visible')) {$('#reportTitle').html(title); return;}
|
||||
}
|
||||
function prepareUnraid(value) {
|
||||
if (value=='') $('.unraid').hide(); else $('.unraid').show();
|
||||
prepareTitle();
|
||||
}
|
||||
function preparePlugin(value) {
|
||||
if (value=='') $('.plugin').hide(); else $('.plugin').show();
|
||||
prepareTitle();
|
||||
}
|
||||
function prepareDocker(value) {
|
||||
if (value=='') $('.docker').hide(); else $('.docker').show();
|
||||
prepareTitle();
|
||||
}
|
||||
function prepareLanguage(value) {
|
||||
if (value=='') $('.language').hide(); else $('.language').show();
|
||||
prepareTitle();
|
||||
}
|
||||
function prepareReport(value) {
|
||||
if (value=='') $('.report').hide(); else $('.report').show();
|
||||
prepareTitle();
|
||||
}
|
||||
$(function(){
|
||||
prepareUnraid(document.notify_settings.unraidos.value);
|
||||
preparePlugin(document.notify_settings.version.value);
|
||||
prepareDocker(document.notify_settings.docker_update.value);
|
||||
prepareLanguage(document.notify_settings.language_update.value);
|
||||
prepareReport(document.notify_settings.status.value);
|
||||
});
|
||||
</script>
|
||||
<form markdown="1" name="notify_settings" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareNotify(this)">
|
||||
<input type="hidden" name="#file" value="dynamix/dynamix.cfg">
|
||||
<input type="hidden" name="#section" value="notify">
|
||||
<input type="hidden" name="#command" value="/webGui/scripts/notify">
|
||||
<input type="hidden" name="#arg[1]" value="cron-init">
|
||||
<input type="hidden" name="entity">
|
||||
<input type="hidden" name="normal">
|
||||
<input type="hidden" name="warning">
|
||||
<input type="hidden" name="alert">
|
||||
<input type="hidden" name="unraid">
|
||||
<input type="hidden" name="plugin">
|
||||
<input type="hidden" name="docker_notify">
|
||||
<input type="hidden" name="language_notify">
|
||||
<input type="hidden" name="report">
|
||||
_(Notifications display)_:
|
||||
: <select class="a" name="display">
|
||||
<?=mk_option($notify['display'], "0", _("Detailed"))?>
|
||||
<?=mk_option($notify['display'], "1", _("Summarized"))?>
|
||||
</select>
|
||||
|
||||
:notifications_display_help:
|
||||
|
||||
_(Date format)_:
|
||||
: <select name="date" class="a">
|
||||
<?=mk_option($notify['date'], "d-m-Y", _("DD-MM-YYYY"))?>
|
||||
<?=mk_option($notify['date'], "m-d-Y", _("MM-DD-YYYY"))?>
|
||||
<?=mk_option($notify['date'], "Y-m-d", _("YYYY-MM-DD"))?>
|
||||
</select>
|
||||
|
||||
:notifications_date_format_help:
|
||||
|
||||
_(Time format)_:
|
||||
: <select name="time" class="a">
|
||||
<?=mk_option($notify['time'], "h:i A", _("12 hours"))?>
|
||||
<?=mk_option($notify['time'], "H:i", _("24 hours"))?>
|
||||
</select>
|
||||
|
||||
:notifications_time_format_help:
|
||||
|
||||
_(Display position)_:
|
||||
: <select name="position" class="a">
|
||||
<?=mk_option($notify['position'], "top-left", _("top-left"))?>
|
||||
<?=mk_option($notify['position'], "top-right", _("top-right"))?>
|
||||
<?=mk_option($notify['position'], "bottom-left", _("bottom-left"))?>
|
||||
<?=mk_option($notify['position'], "bottom-right", _("bottom-right"))?>
|
||||
<?=mk_option($notify['position'], "center", _("center"))?>
|
||||
</select>
|
||||
|
||||
:notifications_display_position_help:
|
||||
|
||||
_(Store notifications to flash)_:
|
||||
: <select name="path" class="a">
|
||||
<?=mk_option($notify['path'], "/tmp/notifications", _("No"))?>
|
||||
<?=mk_option($notify['path'], "/boot/config/plugins/dynamix/notifications", _("Yes"))?>
|
||||
</select>
|
||||
|
||||
:notifications_store_flash_help:
|
||||
|
||||
_(System notifications)_:
|
||||
: <select name="system" class="a" onchange="prepareSystem(this.selectedIndex)">
|
||||
<?=mk_option($notify['system'], "", _("Disabled"))?>
|
||||
<?=mk_option($notify['system'], "*/1 * * * *", _("Enabled"))?>
|
||||
</select>
|
||||
|
||||
:notifications_system_help:
|
||||
|
||||
_(Unraid OS update notification)_:
|
||||
: <select name="unraidos" class="a" onchange="prepareUnraid(this.value)">
|
||||
<?=mk_option($notify['unraidos'], "", _("Never check"))?>
|
||||
<?=mk_option($notify['unraidos'], "11 */6 * * *", _("Check four times a day"))?>
|
||||
<?=mk_option($notify['unraidos'], "11 0,12 * * *", _("Check twice a day"))?>
|
||||
<?=mk_option($notify['unraidos'], "11 0 * * *", _("Check once a day"))?>
|
||||
<?=mk_option($notify['unraidos'], "11 0 * * 1", _("Check once a week"))?>
|
||||
<?=mk_option($notify['unraidos'], "11 0 1 * *", _("Check once a month"))?>
|
||||
</select>
|
||||
|
||||
:notifications_os_update_help:
|
||||
|
||||
_(Plugins update notification)_:
|
||||
: <select name="version" class="a" onchange="preparePlugin(this.value)">
|
||||
<?=mk_option($notify['version'], "", _("Never check"))?>
|
||||
<?=mk_option($notify['version'], "10 */6 * * *", _("Check four times a day"))?>
|
||||
<?=mk_option($notify['version'], "10 0,12 * * *", _("Check twice a day"))?>
|
||||
<?=mk_option($notify['version'], "10 0 * * *", _("Check once a day"))?>
|
||||
<?=mk_option($notify['version'], "10 0 * * 1", _("Check once a week"))?>
|
||||
<?=mk_option($notify['version'], "10 0 1 * *", _("Check once a month"))?>
|
||||
</select>
|
||||
|
||||
:notifications_plugins_update_help:
|
||||
|
||||
_(Docker update notification)_:
|
||||
: <select name="docker_update" class="a" onchange="prepareDocker(this.value)">
|
||||
<?=mk_option($notify['docker_update'], "", _("Never check"))?>
|
||||
<?=mk_option($notify['docker_update'], "10 */6 * * *", _("Check four times a day"))?>
|
||||
<?=mk_option($notify['docker_update'], "10 0,12 * * *", _("Check twice a day"))?>
|
||||
<?=mk_option($notify['docker_update'], "10 0 * * *", _("Check once a day"))?>
|
||||
<?=mk_option($notify['docker_update'], "10 0 * * 1", _("Check once a week"))?>
|
||||
<?=mk_option($notify['docker_update'], "10 0 1 * *", _("Check once a month"))?>
|
||||
</select>
|
||||
|
||||
:notifications_docker_update_help:
|
||||
|
||||
_(Language update notification)_:
|
||||
: <select name="language_update" class="a" onchange="prepareLanguage(this.value)">
|
||||
<?=mk_option($notify['language_update'], "", _("Never check"))?>
|
||||
<?=mk_option($notify['language_update'], "10 */6 * * *", _("Check four times a day"))?>
|
||||
<?=mk_option($notify['language_update'], "10 0,12 * * *", _("Check twice a day"))?>
|
||||
<?=mk_option($notify['language_update'], "10 0 * * *", _("Check once a day"))?>
|
||||
<?=mk_option($notify['language_update'], "10 0 * * 1", _("Check once a week"))?>
|
||||
<?=mk_option($notify['language_update'], "10 0 1 * *", _("Check once a month"))?>
|
||||
</select>
|
||||
|
||||
_(Array status notification)_:
|
||||
: <select name="status" class="a" onchange="prepareReport(this.value)">
|
||||
<?=mk_option($notify['status'], "", _("Never send"))?>
|
||||
<?=mk_option($notify['status'], "20 * * * *", _("Send every hour"))?>
|
||||
<?=mk_option($notify['status'], "20 */2 * * *", _("Send every two hours"))?>
|
||||
<?=mk_option($notify['status'], "20 */6 * * *", _("Send four times a day"))?>
|
||||
<?=mk_option($notify['status'], "20 */8 * * *", _("Send three times a day"))?>
|
||||
<?=mk_option($notify['status'], "20 0,12 * * *", _("Send twice a day"))?>
|
||||
<?=mk_option($notify['status'], "20 0 * * *", _("Send once a day"))?>
|
||||
<?=mk_option($notify['status'], "20 0 * * 1", _("Send once a week"))?>
|
||||
<?=mk_option($notify['status'], "20 0 1 * *", _("Send once a month"))?>
|
||||
</select>
|
||||
|
||||
:notifications_array_status_help:
|
||||
|
||||
<span id="unraidTitle" class="unraid" style="display:none"> </span>
|
||||
: <span class="unraid" style="display:none"><span class="a">_(Unraid OS update)_</span>
|
||||
<input type="checkbox" name="unraid1"<?=($notify['unraid'] & 1)==1 ? ' checked' : ''?>>_(Browser)_
|
||||
<input type="checkbox" name="unraid2"<?=($notify['unraid'] & 2)==2 ? ' checked' : ''?>>_(Email)_
|
||||
<input type="checkbox" name="unraid3"<?=($notify['unraid'] & 4)==4 ? ' checked' : ''?>>_(Agents)_ </span>
|
||||
|
||||
<span id="pluginTitle" class="plugin" style="display:none"> </span>
|
||||
: <span class="plugin" style="display:none"><span class="a">_(Plugins update)_</span>
|
||||
<input type="checkbox" name="plugin1"<?=($notify['plugin'] & 1)==1 ? ' checked' : ''?>>_(Browser)_
|
||||
<input type="checkbox" name="plugin2"<?=($notify['plugin'] & 2)==2 ? ' checked' : ''?>>_(Email)_
|
||||
<input type="checkbox" name="plugin3"<?=($notify['plugin'] & 4)==4 ? ' checked' : ''?>>_(Agents)_ </span>
|
||||
|
||||
<span id="dockerTitle" class="docker" style="display:none"> </span>
|
||||
: <span class="docker" style="display:none"><span class="a">_(Docker update)_</span>
|
||||
<input type="checkbox" name="docker_notify1"<?=($notify['docker_notify'] & 1)==1 ? ' checked' : ''?>>_(Browser)_
|
||||
<input type="checkbox" name="docker_notify2"<?=($notify['docker_notify'] & 2)==2 ? ' checked' : ''?>>_(Email)_
|
||||
<input type="checkbox" name="docker_notify3"<?=($notify['docker_notify'] & 4)==4 ? ' checked' : ''?>>_(Agents)_ </span>
|
||||
|
||||
<span id="languageTitle" class="language" style="display:none"> </span>
|
||||
: <span class="language" style="display:none"><span class="a">_(Language update)_</span>
|
||||
<input type="checkbox" name="language_notify1"<?=($notify['language_notify'] & 1)==1 ? ' checked' : ''?>>_(Browser)_
|
||||
<input type="checkbox" name="language_notify2"<?=($notify['language_notify'] & 2)==2 ? ' checked' : ''?>>_(Email)_
|
||||
<input type="checkbox" name="language_notify3"<?=($notify['language_notify'] & 4)==4 ? ' checked' : ''?>>_(Agents)_ </span>
|
||||
|
||||
<span id="reportTitle" class="report" style="display:none"> </span>
|
||||
: <span class="report" style="display:none"><span class="a">_(Array status)_</span>
|
||||
<input type="checkbox" name="report1"<?=($notify['report'] & 1)==1 ? ' checked' : ''?>>_(Browser)_
|
||||
<input type="checkbox" name="report2"<?=($notify['report'] & 2)==2 ? ' checked' : ''?>>_(Email)_
|
||||
<input type="checkbox" name="report3"<?=($notify['report'] & 4)==4 ? ' checked' : ''?>>_(Agents)_ </span>
|
||||
|
||||
:notifications_agent_selection_help:
|
||||
|
||||
_(Notification entity)_:
|
||||
: <span class="a">_(Notices)_</span>
|
||||
<input type="checkbox" class="checkbox" name="normal1"<?=($notify['normal'] & 1)==1 ? " checked $disabled" : $disabled?>>_(Browser)_
|
||||
<input type="checkbox" class="checkbox" name="normal2"<?=($notify['normal'] & 2)==2 ? " checked $disabled" : $disabled?>>_(Email)_
|
||||
<input type="checkbox" class="checkbox" name="normal3"<?=($notify['normal'] & 4)==4 ? " checked $disabled" : $disabled?>>_(Agents)_
|
||||
|
||||
|
||||
: <span class="a">_(Warnings)_</span>
|
||||
<input type="checkbox" class="checkbox" name="warning1"<?=($notify['warning'] & 1)==1 ? " checked $disabled" : $disabled?>>_(Browser)_
|
||||
<input type="checkbox" class="checkbox" name="warning2"<?=($notify['warning'] & 2)==2 ? " checked $disabled" : $disabled?>>_(Email)_
|
||||
<input type="checkbox" class="checkbox" name="warning3"<?=($notify['warning'] & 4)==4 ? " checked $disabled" : $disabled?>>_(Agents)_
|
||||
|
||||
|
||||
: <span class="a">_(Alerts)_</span>
|
||||
<input type="checkbox" class="checkbox" name="alert1"<?=($notify['alert'] & 1)==1 ? " checked $disabled" : $disabled?>>_(Browser)_
|
||||
<input type="checkbox" class="checkbox" name="alert2"<?=($notify['alert'] & 2)==2 ? " checked $disabled" : $disabled?>>_(Email)_
|
||||
<input type="checkbox" class="checkbox" name="alert3"<?=($notify['alert'] & 4)==4 ? " checked $disabled" : $disabled?>>_(Agents)_
|
||||
|
||||
:notifications_classification_help:
|
||||
|
||||
<input type="submit" name="#default" value="_(Default)_">
|
||||
: <input type="submit" name="#apply" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
@@ -0,0 +1,114 @@
|
||||
Menu="UNRAID-OS"
|
||||
Title="Archived Notifications"
|
||||
Icon="icon-archive"
|
||||
Tag="archive"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2012, Andrew Hamer-Adams, http://www.pixeleyes.co.nz.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$files = count(glob("{$notify['path']}/archive/*.notify", GLOB_NOSORT));
|
||||
$filters = mk_option(0,'',_('No filter')).mk_option(0,'alert',_('Alerts')).mk_option(0,'warning',_('Warnings')).mk_option(0,'normal',_('Notices'));
|
||||
?>
|
||||
<style>
|
||||
select.filter{margin:0}
|
||||
span.right{margin-top:-6px;font-size:1.3rem!important;padding:0!important}
|
||||
i.red-text{font-size:1.6rem}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
var rows = [];
|
||||
var filter = "<?=unscript(_var($_GET,'filter'))?>";
|
||||
var files = -1;
|
||||
|
||||
Array.prototype.remove = function() {
|
||||
var val, a = arguments, L = a.length, ax;
|
||||
while (L && this.length) {
|
||||
val = a[--L];
|
||||
while ((ax = this.indexOf(val)) !== -1) this.splice(ax, 1);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
<?if (_var($display,'resize')):?>
|
||||
function resize() {
|
||||
$('#archive_list').height(Math.max(window.innerHeight-340,330));
|
||||
$('#archive_table thead,#archive_table tbody').removeClass('fixed');
|
||||
$('#archive_table thead tr th').each(function(){$(this).width($(this).width());});
|
||||
$('#archive_table tbody tr td').each(function(){$(this).width($(this).width());});
|
||||
$('#archive_table thead,#archive_table tbody').addClass('fixed');
|
||||
}
|
||||
<?endif;?>
|
||||
function archiveList(init) {
|
||||
clearTimeout(timers.archivelist);
|
||||
timers.archive = setTimeout(function(){$('div.spinner.fixed').show('slow');},500);
|
||||
$.get('/webGui/include/NotificationsArchive.php',{filter:filter},function(data) {
|
||||
clearTimeout(timers.archive);
|
||||
data = data.split('\0');
|
||||
if (data[1]>0) $('#deleteAll').show(); else $('#deleteAll').hide();
|
||||
if (files != data[1]) {
|
||||
files = data[1];
|
||||
$('#archive_list').html(data[0]);
|
||||
<?if (_var($display,'resize')):?>
|
||||
resize();
|
||||
<?endif;?>
|
||||
if (init) {
|
||||
<?if (_var($display,'resize')):?>
|
||||
$(window).bind('resize',function(){resize();});
|
||||
<?endif;?>
|
||||
$('#archive_table').tablesorter({headers:{5:{sorter:false}},textAttribute:'data'});
|
||||
} else {
|
||||
$('#archive_table').trigger('update');
|
||||
}
|
||||
$('#archive_list .tablesorter-childRow td').hide();
|
||||
for (var i=0; i < rows.length; i++) $('#archive_list .tablesorter-childRow.row'+rows[i]+' td').show();
|
||||
}
|
||||
$('div.spinner.fixed').hide('slow');
|
||||
timers.archivelist = setTimeout(archiveList,3000);
|
||||
});
|
||||
}
|
||||
function askConfirmation() {
|
||||
swal({
|
||||
title:"_(Are you sure)_?",
|
||||
text: filter=='' ? "_(This will delete all notification files)_!" : "_(This will delete the selected notification files)_!",
|
||||
type:"warning",
|
||||
html:true,
|
||||
showCancelButton:true,
|
||||
confirmButtonText:"_(Proceed)_",
|
||||
cancelButtonText:"_(Cancel)_"
|
||||
},
|
||||
function(){$.post('/webGui/include/DeleteLogFile.php',{log:'*.notify',filter:filter},function(){$('#deleteAll').hide();archiveList();});});
|
||||
}
|
||||
function openClose(row) {
|
||||
var extra = '#archive_list .tablesorter-childRow.row'+row+' td';
|
||||
if ($(extra).is(":visible")) {
|
||||
$(extra).hide();
|
||||
rows.remove(row);
|
||||
} else {
|
||||
$(extra).show();
|
||||
rows.push(row);
|
||||
}
|
||||
}
|
||||
$(function(){
|
||||
$('span.left').append("<span class='right'><select class='filter narrow' onchange='filter=this.value;archiveList()'><?=$filters?></select></span>");
|
||||
$('select.filter').val(filter);
|
||||
archiveList(true);
|
||||
});
|
||||
|
||||
// Adjust the width of thead cells when window resizes
|
||||
</script>
|
||||
<table class="tablesorter left shift" id="archive_table">
|
||||
<thead><tr><th>_(Time)_</th><th>_(Event)_</th><th>_(Subject)_</th><th>_(Description)_</th><th>_(Importance)_</th><th><a id="deleteAll" href="#" onclick="askConfirmation();return false" title="_(Delete all notifications)_" style="display:none"><i class="fa fa-trash-o red-text"></i></a></th></tr></thead>
|
||||
<tbody id="archive_list"><tr><td colspan="6"></td></tr></tbody>
|
||||
</table>
|
||||
<input type="button" value="_(Done)_" onclick="done()">
|
||||
@@ -0,0 +1,38 @@
|
||||
Menu="Main:4"
|
||||
Title="Unassigned Devices"
|
||||
Tag="unlink"
|
||||
Cond="(count($devs)>0)"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
* Copyright 2012-2021, 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$tabX = '#tab'.($var['fsState']=='Stopped'||$pool_devices ? '4' : '3');
|
||||
?>
|
||||
<script>
|
||||
<?if ($var['fsState']=='Started'):?>
|
||||
$('<?=$tabX?>').bind({click:function() {$('i.toggle').show('slow');}});
|
||||
<?endif;?>
|
||||
</script>
|
||||
|
||||
<table class="disk_status wide">
|
||||
<thead><tr><td>_(Device)_</td><td>_(Identification)_</td><td>_(Temp)_.</td><td>_(Reads)_</td><td>_(Writes)_</td><td>_(Errors)_</td><td>_(FS)_</td><td>_(Size)_</td><td>_(Used)_</td><td>_(Free)_</td></tr></thead>
|
||||
<tbody id="open_devices">
|
||||
<?
|
||||
foreach ($devs as $dev):
|
||||
echo "<tr><td colspan='11'> </td></tr>";
|
||||
endforeach;
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
:open_devices_help:
|
||||
@@ -0,0 +1,4 @@
|
||||
Menu="Settings:1"
|
||||
Type="menu"
|
||||
Title="System Settings"
|
||||
Tag="cog"
|
||||
@@ -0,0 +1,183 @@
|
||||
Menu="WebGui"
|
||||
Title="PHP Settings"
|
||||
Icon="icon-template"
|
||||
Tag="edit"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$log = "/var/log/phplog";
|
||||
$ini = "/etc/php.d/errors-php.ini";
|
||||
$conf = file_exists($ini) ? parse_ini_file($ini) : [];
|
||||
if (!file_exists($log)) touch($log);
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/jquery.ui.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/plugins/dynamix.docker.manager/styles/style-$theme.css")?>">
|
||||
|
||||
<style>
|
||||
div#templateWindow,div#dialogWindow{display:none}
|
||||
span.dim{opacity:0.2}
|
||||
#screenlog{margin-left:0}
|
||||
</style>
|
||||
|
||||
<div markdown="1" style="width:43%;margin-bottom:40px;padding:5px 15px;border:solid 1px">
|
||||
:php_settings_plug:
|
||||
This utility is used for development purposes only and allows Plugin Authors to verify their PHP code by enabling different levels of PHP error reporting.
|
||||
|
||||
By default error logging is minimum and any errors are shown on screen. Changing the **Error reporting level** will capture the selected level of errors
|
||||
into a LOG file, which can be opened in a separate window to monitor in real-time the events when visiting various GUI pages or executing background
|
||||
processes on the server.
|
||||
|
||||
The LOG file can quickly grow large when multiple errors exists, it is advised to use it only during development and use the default setting
|
||||
under normal running conditions.
|
||||
:end
|
||||
</div>
|
||||
|
||||
<form markdown="1" name="php_settings" method="POST" action="/update.php" target="progressFrame" onsubmit="preset(this)">
|
||||
<input type="hidden" name="#cleanup" value="1">
|
||||
<input type="hidden" name="#file" value="<?=$ini?>">
|
||||
<input type="hidden" name="error_log" value="<?=$log?>">
|
||||
<input type="hidden" name="display_startup_errors" value="0">
|
||||
<input type="hidden" name="display_errors" value="<?=_var($conf,'display_errors',0)?>">
|
||||
<input type="hidden" name="log_errors" value="1">
|
||||
_(Error reporting level)_:
|
||||
: <select name="error_reporting" onchange="toggleScreen(this.selectedIndex)">
|
||||
<?=mk_option(_var($conf,'error_reporting'), "", "_(Default)_");?>
|
||||
<?=mk_option(_var($conf,'error_reporting'), "32767", "_(All Categories)_");?>
|
||||
<?=mk_option(_var($conf,'error_reporting'), "1", "_(Errors Only)_");?>
|
||||
<?=mk_option(_var($conf,'error_reporting'), "2", "_(Warnings Only)_");?>
|
||||
<?=mk_option(_var($conf,'error_reporting'), "8", "_(Notices Only)_");?>
|
||||
<?=mk_option(_var($conf,'error_reporting'), "8192", "_(Deprecated Only)_");?>
|
||||
</select>
|
||||
|
||||
|
||||
: <input type="checkbox" id="screenlog" onclick="screenLog()" <?=_var($conf,'display_errors',0)?'checked':''?> disabled><span id="screentext" class="dim">_(Show errors on screen)_</span>
|
||||
|
||||
<input type="button" value="_(PHP Info)_" onclick="PHPinfo()"><input type="button" id="clearlog" value="_(Clear Log)_" onclick="clearLog()"<?=filesize($log)>0?'':' disabled'?>><input type="button" id="viewlog" value="_(View Log)_" onclick="viewLog()" disabled>_(LOG size)_: <span id="logsize"></span>
|
||||
: <input type="submit" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
|
||||
<div id="dialogWindow"></div>
|
||||
|
||||
<div markdown="1" id="templateWindow">
|
||||
<!--!
|
||||
<html <?=$display['rtl']?>lang="<?=strtok($locale,'_')?:'en'?>">
|
||||
<style>
|
||||
table{box-shadow:1px 2px 3px rgba(0,0,0,0.2);width:90%}
|
||||
.center{text-align:center;color:#f2f2f2!important;background-color:#1c1b1b}
|
||||
.center table{margin:1em auto;text-align:left}
|
||||
.center th{text-align:center!important}
|
||||
td,th{border:1px solid #505153;vertical-align:baseline;padding:4px 5px!important;color:#f2f2f2}
|
||||
th{position:sticky;top:0}
|
||||
img{float:right;border:0}
|
||||
hr{width:90%;background-color:#505153;border:0;height:1px}
|
||||
h1{font-size:150%}
|
||||
h2{font-size:125%}
|
||||
h2 a{color:#f2f2f2!important}
|
||||
.p{text-align:left}
|
||||
.e{background-color:#404A77;width:300px}
|
||||
.h{background-color:#4F5B93}
|
||||
.v{background-color:#333;max-width:300px;overflow-x:auto;word-wrap:break-word}
|
||||
.v i{color:#999}
|
||||
.h td,td.e,th{border-color:#606A90}
|
||||
</style>
|
||||
<body>
|
||||
<?
|
||||
ob_start();
|
||||
phpinfo();
|
||||
echo preg_replace('/^<!DOCTYPE html .*<body>/s','',ob_get_clean());
|
||||
?>
|
||||
|
||||
!-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
String.prototype.build = function(){return this.replace(/\n(<!--!|!-->)\n/g,'');}
|
||||
|
||||
var box = null;
|
||||
|
||||
function screenLog() {
|
||||
$('input[name="display_errors"]').val($('#screenlog').prop('checked')?1:0);
|
||||
}
|
||||
function viewLog() {
|
||||
openTerminal('log','PHP Error Log','phplog');
|
||||
}
|
||||
function clearLog() {
|
||||
$.post('/webGui/include/PHPsettings.php',{cmd:'clear'},function(){
|
||||
swal({title:"_(PHP Log File)_",text:"_(Log file cleared)_",type:'success',html:true,confirmButtonText:"_(Ok)_"},function(){
|
||||
if (tty_window==null) viewLog();
|
||||
tty_window.close();
|
||||
$('#clearlog').prop('disabled',true);
|
||||
});
|
||||
});
|
||||
}
|
||||
function logSize() {
|
||||
$.post('/webGui/include/PHPsettings.php',{cmd:'logsize'},function(size){
|
||||
$('#logsize').text(size);
|
||||
if (size.split(' ')[0]!=0) {$('#clearlog').prop('disabled',false);$('#viewlog').prop('disabled',false);}
|
||||
setTimeout(logSize,3000);
|
||||
});
|
||||
}
|
||||
function PHPinfo() {
|
||||
box = $("#dialogWindow");
|
||||
box.html($("#templateWindow").html().build());
|
||||
box.dialog({
|
||||
title: "_(PHP Information)_",
|
||||
resizable: false,
|
||||
height: Math.min(window.innerHeight-80,800),
|
||||
width: Math.min(window.innerWidth,1200),
|
||||
modal: true,
|
||||
show: {effect:'fade', duration:250},
|
||||
hide: {effect:'fade', duration:250},
|
||||
buttons: {
|
||||
"_(Done)_": function(){
|
||||
box.dialog('close');
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.ui-dialog-titlebar-close').css({'display':'none'});
|
||||
$('.ui-dialog-title').css({'text-align':'center','width':'100%','font-size':'1.8rem'});
|
||||
$('.ui-button-text').css({'padding':'0 5px'});
|
||||
}
|
||||
function preset(form) {
|
||||
// reset to default settings
|
||||
if (form.error_reporting.selectedIndex==0) {
|
||||
form.error_log.value = "";
|
||||
form.display_startup_errors.value = "";
|
||||
form.display_errors.value = "";
|
||||
form.log_errors.value = "";
|
||||
}
|
||||
$.cookie('reload_php',1);
|
||||
}
|
||||
function toggleScreen(index) {
|
||||
if (index > 0) {
|
||||
$('#screenlog').prop('disabled',false);
|
||||
$('#screentext').removeClass('dim');
|
||||
} else {
|
||||
$('#screenlog').prop('disabled',true);
|
||||
$('#screentext').addClass('dim');
|
||||
}
|
||||
}
|
||||
$(function(){
|
||||
logSize();
|
||||
if (document.php_settings.error_reporting.selectedIndex > 0) {
|
||||
$('#viewlog').prop('disabled',false);
|
||||
$('#screenlog').prop('disabled',false);
|
||||
$('#screentext').removeClass('dim');
|
||||
}
|
||||
if ($.cookie('reload_php')==1) {
|
||||
$.removeCookie('reload_php');
|
||||
$.post('/webGui/include/PHPsettings.php',{cmd:'reload'});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,66 @@
|
||||
Menu="WebGui"
|
||||
Title="Page Map"
|
||||
Icon="icon-pagemap"
|
||||
Tag="map-o"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?if (_var($display,'resize')):?>
|
||||
<script>
|
||||
function resize() {
|
||||
$('div.up').height(Math.max(window.innerHeight-320,330));
|
||||
}
|
||||
$(function() {
|
||||
resize();
|
||||
$(window).bind('resize',function(){resize();});
|
||||
});
|
||||
</script>
|
||||
<?endif;?>
|
||||
<?
|
||||
function show_map($menu, $level) {
|
||||
$pages = find_pages( $menu);
|
||||
if (empty($pages))
|
||||
return;
|
||||
echo "<ul>";
|
||||
foreach ($pages as $page) {
|
||||
$link = "<a href='/{$page['name']}'>{$page['name']}</a>";
|
||||
$title = _($page['Title'] ?? '');
|
||||
$type = $page['Type'] ?? '';
|
||||
if ($type == "menu") {
|
||||
$link = "($link)";
|
||||
} elseif ($type == "xmenu") {
|
||||
$link = "[$link]";
|
||||
}
|
||||
echo "$level $link",($title ? " - $title" : ""),"<br>";
|
||||
show_map($page['name'], $level+1);
|
||||
}
|
||||
echo "</ul>";
|
||||
}
|
||||
$uri = ['dashboard','main','shares','users','settings','plugins','docker','vms'];
|
||||
|
||||
foreach($uri as $more) {
|
||||
$text = "$docroot/languages/$locale/$more.txt";
|
||||
if (file_exists($text)) {
|
||||
// additional translations
|
||||
$store = "$docroot/languages/$locale/$more.dot";
|
||||
if (!file_exists($store)) file_put_contents($store,serialize(parse_lang_file($text)));
|
||||
$language = array_merge($language,unserialize(file_get_contents($store)));
|
||||
}
|
||||
}
|
||||
|
||||
echo "<div class='up'>";
|
||||
show_map("Tasks", 1);
|
||||
show_map("Buttons", 1);
|
||||
echo "</div>";
|
||||
?>
|
||||
<input type="button" value="_(Done)_" onclick="done()">
|
||||
@@ -0,0 +1,229 @@
|
||||
Menu="Scheduler:1"
|
||||
Title="Parity Check"
|
||||
Tag="calendar"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2005-2023, Lime Technology
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
if (_var($disks['parity'],'status')=='DISK_NP_DSBL' && _var($disks['parity2'],'status')=='DISK_NP_DSBL') {
|
||||
echo "<p class='notice'>"._('No Parity disk present')."!</p>";
|
||||
}
|
||||
$width = [166,300];
|
||||
$mode = ['Disabled','Daily','Weekly','Monthly','Yearly','Custom'];
|
||||
$days = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
|
||||
$months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
|
||||
$memory = '/tmp/memory.tmp';
|
||||
|
||||
if (file_exists($memory)) {
|
||||
parse_str(file_get_contents($memory), $parity);
|
||||
if (empty($parity['hour'])) $parity['hour'] = "";
|
||||
if (empty($parity['day'])) $parity['day'] = "";
|
||||
if (empty($parity['dotm'])) $parity['dotm'] = "";
|
||||
if (empty($parity['month'])) $parity['month'] = "";
|
||||
if (empty($parity['write'])) $parity['write'] = "NOCORRECT";
|
||||
}
|
||||
if ($parity['mode']<2) $parity['cumulative'] = '';
|
||||
if ($parity['mode']==2) $parity['frequency'] = '1';
|
||||
?>
|
||||
<script>
|
||||
<?if ($parity['mode']==5):?>
|
||||
$(function() {
|
||||
$("#s1").dropdownchecklist({emptyText:"_(Every day)_", width:<?=$width[0]?>, explicitClose:"..._(close)_"});
|
||||
$("#s2").dropdownchecklist({emptyText:"_(Every month)_", width:<?=$width[0]?>, explicitClose:"..._(close)_"});
|
||||
});
|
||||
// Simulate a single input field
|
||||
function prepareParity(form) {
|
||||
var days = '';
|
||||
for (var i=0,item; item=form.day.options[i]; i++) {
|
||||
if (item.selected) {
|
||||
if (days.length) days += ',';
|
||||
days += item.value;
|
||||
item.selected = false;
|
||||
}
|
||||
}
|
||||
item = form.day.options[0];
|
||||
item.value = days || '*';
|
||||
item.selected = true;
|
||||
var months = '';
|
||||
for (var i=0,item; item=form.month.options[i]; i++) {
|
||||
if (item.selected) {
|
||||
if (months.length) months += ',';
|
||||
months += item.value;
|
||||
item.selected = false;
|
||||
}
|
||||
}
|
||||
item = form.month.options[0];
|
||||
item.value = months || '*';
|
||||
item.selected = true;
|
||||
}
|
||||
<?else:?>
|
||||
function prepareParity(form) {
|
||||
// do nothing
|
||||
}
|
||||
<?endif;?>
|
||||
$(function() {
|
||||
<?if (file_exists($memory)):?>
|
||||
setTimeout(function(){$('input[value="_(Apply)_"]').removeAttr('disabled');},0);
|
||||
$('input[value="_(Done)_"]').val("_(Reset)_").prop('onclick',null).click(function(){refresh($(this).parentsUntil('form').parent().offset().top)});
|
||||
<?unlink($memory);?>
|
||||
<?endif;?>
|
||||
presetParity(document.parity_settings);
|
||||
});
|
||||
function presetParity(form) {
|
||||
var mode = form.mode.value;
|
||||
form.day.disabled = mode!=2 && mode!=5;
|
||||
form.dotm.disabled = mode<3;
|
||||
form.hour.disabled = mode==0;
|
||||
form.month.disabled = mode<4;
|
||||
form.write.disabled = mode==0;
|
||||
}
|
||||
function showCumulative(val,pace) {
|
||||
if (val=='') $('#cumulative').hide(pace); else $('#cumulative').show(pace);
|
||||
}
|
||||
$(function(){
|
||||
showCumulative($('select[name="cumulative"]').val());
|
||||
});
|
||||
</script>
|
||||
<form markdown="1" name="parity_settings" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareParity(this)">
|
||||
<input type="hidden" name="#file" value="dynamix/dynamix.cfg"/>
|
||||
<input type="hidden" name="#section" value="parity"/>
|
||||
<input type="hidden" name="#include" value="/webGui/include/update.parity.php"/>
|
||||
_(Scheduled parity check)_:
|
||||
: <select name="mode" onchange="submit()">
|
||||
<?for ($m=0; $m<count($mode); $m++):?>
|
||||
<?=mk_option($parity['mode'], strval($m), _($mode[$m]))?>
|
||||
<?endfor;?>
|
||||
</select>
|
||||
|
||||
:parity_check_scheduled_help:
|
||||
|
||||
_(Day of the week)_:
|
||||
<?if ($parity['mode']==2):?>
|
||||
: <select name="day">
|
||||
<?for ($d=0; $d<count($days); $d++):?>
|
||||
<?=mk_option($parity['day'], strval($d), ucfirst(_($days[$d],0)))?>
|
||||
<?endfor;?>
|
||||
<?elseif ($parity['mode']==5):?>
|
||||
: <select id="s1" name="day" multiple="multiple" style="display:none">
|
||||
<?for ($d=0; $d<count($days); $d++):?>
|
||||
<?=mk_option_check($parity['day'], strval($d), ucfirst(_($days[$d],0)))?>
|
||||
<?endfor;?>
|
||||
<?else:?>
|
||||
: <select name="day">
|
||||
<?=mk_option($parity['day'], "*", "--------")?>
|
||||
<?endif;?>
|
||||
</select>
|
||||
|
||||
:parity_day_of_the_week_help:
|
||||
|
||||
<?if ($parity['mode']<5):?>
|
||||
_(Day of the month)_:
|
||||
<?else:?>
|
||||
_(Week of the month)_:
|
||||
<?endif;?>
|
||||
: <select name="dotm">
|
||||
<?if ($parity['mode']>=3):?>
|
||||
<?if ($parity['mode']==5):?>
|
||||
<?=mk_option($parity['dotm'], "*", _("Every week"))?>
|
||||
<?=mk_option($parity['dotm'], "W1", _("First week"))?>
|
||||
<?=mk_option($parity['dotm'], "W2", _("Second week"))?>
|
||||
<?=mk_option($parity['dotm'], "W3", _("Third week"))?>
|
||||
<?=mk_option($parity['dotm'], "W4", _("Fourth week"))?>
|
||||
<?=mk_option($parity['dotm'], "WL", _("Last week"))?>
|
||||
<?else:?>
|
||||
<?=mk_option($parity['dotm'], "1", _("First day"))?>
|
||||
<?=mk_option($parity['dotm'], "28-31", _("Last day"))?>
|
||||
<?for ($d=2; $d<=31; $d++):?>
|
||||
<?=mk_option($parity['dotm'], strval($d), sprintf("%02d", $d))?>
|
||||
<?endfor;?>
|
||||
<?endif;?>
|
||||
<?else:?>
|
||||
<?=mk_option($parity['dotm'], "*", "--------")?>
|
||||
<?endif;?>
|
||||
</select>
|
||||
|
||||
:parity_week_of_the_month_help:
|
||||
|
||||
_(Time of the day)_:
|
||||
: <select name="hour">
|
||||
<?if ($parity['mode']>0):?>
|
||||
<?for ($h=0; $h<24; $h++):?>
|
||||
<?=mk_option($parity['hour'], sprintf("0 %d", $h), sprintf("%02d:00", $h))?>
|
||||
<?=mk_option($parity['hour'], sprintf("30 %d",$h), sprintf("%02d:30", $h))?>
|
||||
<?endfor;?>
|
||||
<?else:?>
|
||||
<?=mk_option($parity['hour'], "*", "--------")?>
|
||||
<?endif;?>
|
||||
</select>
|
||||
|
||||
:parity_time_of_the_day_help:
|
||||
|
||||
_(Month of the year)_:
|
||||
<?if ($parity['mode']>=4):?>
|
||||
<?if ($parity['mode']==5):?>
|
||||
: <select id="s2" name="month" multiple="multiple" style="display:none">
|
||||
<?for ($m=0; $m<count($months); $m++):?>
|
||||
<?=mk_option_check($parity['month'], strval($m+1), ucfirst(_($months[$m],0)))?>
|
||||
<?endfor;?>
|
||||
<?else:?>
|
||||
: <select name="month">
|
||||
<?for ($m=0; $m<count($months); $m++):?>
|
||||
<?=mk_option($parity['month'], strval($m+1), ucfirst(_($months[$m],0)))?>
|
||||
<?endfor;?>
|
||||
<?endif;?>
|
||||
<?else:?>
|
||||
: <select name="month">
|
||||
<?=mk_option($parity['month'], "*", "--------")?>
|
||||
<?endif;?>
|
||||
</select>
|
||||
|
||||
:parity_month_of_the_year_help:
|
||||
|
||||
_(Write corrections to parity disk)_:
|
||||
: <select name="write">
|
||||
<?=mk_option($parity['write'], "NOCORRECT", _("No"))?>
|
||||
<?=mk_option($parity['write'], "", _("Yes"))?>
|
||||
</select>
|
||||
|
||||
:parity_write_corrections_help:
|
||||
|
||||
_(Cumulative parity check)_:
|
||||
: <select name="cumulative" onchange="showCumulative(this.value,'slow')" <?=$parity['mode']>1?'':'disabled'?>>
|
||||
<?=mk_option(_var($parity,'cumulative'), "", _("No"))?>
|
||||
<?=mk_option(_var($parity,'cumulative'), "1", _("Yes"))?>
|
||||
</select>
|
||||
|
||||
:parity_cumulative_check_help:
|
||||
|
||||
<div markdown="1" id="cumulative" style="display:none">
|
||||
_(Accumulation frequency)_:
|
||||
: <select name="frequency">
|
||||
<?=mk_option(_var($parity,'frequency'), "1", _("Daily"))?>
|
||||
<?=mk_option(_var($parity,'frequency'), "7", _("Weekly"),$parity['mode']==2 ? 'disabled' : '')?>
|
||||
</select>
|
||||
|
||||
:parity_accumulation_frequency_help:
|
||||
|
||||
_(Accumulation duration)_:
|
||||
: <select name="duration">
|
||||
<?for ($h=1; $h<24; $h++):?>
|
||||
<?=mk_option(_var($parity,'duration'), $h, $h.' '._('hour'.($h==1?'':'s')))?>
|
||||
<?endfor;?>
|
||||
</select>
|
||||
|
||||
:parity_accumulation_duration_help:
|
||||
|
||||
</div>
|
||||
|
||||
: <input type="submit" name="#apply" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()"></td>
|
||||
</form>
|
||||
@@ -0,0 +1,32 @@
|
||||
Menu="UNRAID-OS"
|
||||
Title="Processes"
|
||||
Icon="icon-processes"
|
||||
Tag="cogs"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?if (_var($display,'resize')):?>
|
||||
<script>
|
||||
function resize() {
|
||||
$('pre.up').height(Math.max(window.innerHeight-320,330));
|
||||
}
|
||||
$(function() {
|
||||
resize();
|
||||
$(window).bind('resize',function(){resize();});
|
||||
});
|
||||
</script>
|
||||
<?endif;?>
|
||||
<?
|
||||
echo "<pre class='up'>",shell_exec('ps -aux'),"</pre>";
|
||||
?>
|
||||
<input type="button" value="_(Done)_" onclick="done()">
|
||||
@@ -0,0 +1,5 @@
|
||||
**Dynamix webGui**
|
||||
|
||||
The *Dynamix* webGui is the latest iteration of the Unraid OS System
|
||||
Management Utility. Built upon *Simple Features*, it provides real-time
|
||||
screen updates, tabbed viewing and many more enhancements.
|
||||
@@ -0,0 +1,102 @@
|
||||
Menu="NetworkSettings"
|
||||
Title="Routing Table"
|
||||
Tag="icon-share"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
unset($list,$other);
|
||||
exec("ls /sys/class/net|grep -P '^br[0-9]'",$list);
|
||||
exec("ls /sys/class/net|grep -P '^(bond|eth)[0-9]'",$other);
|
||||
foreach ($other as $port) {
|
||||
if (substr($port,0,4)=='bond') {
|
||||
$br = str_replace('bond','br',$port);
|
||||
if (!in_array($br,$list)) $list[] = $port;
|
||||
} else {
|
||||
$br = str_replace('eth','br',$port);
|
||||
$bond = str_replace('eth','bond',$port);
|
||||
if (!in_array($br,$list) && !in_array($bond,$list)) $list[] = $port;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
input.fixed{width:200px;}
|
||||
<?if ($themes1):?>
|
||||
span.status.vhshift{margin-right:-10px!important}
|
||||
<?endif;?>
|
||||
</style>
|
||||
<script>
|
||||
function deleteRoute(gateway,route,metric) {
|
||||
swal({title:"Delete route?",text:route+" by gateway "+gateway,type:"warning",html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(){
|
||||
$.post('/webGui/include/RoutingTable.php',{gateway:gateway,route:route,metric:metric,task:'delete'},function(){resetTable();});
|
||||
});
|
||||
}
|
||||
function routeTable() {
|
||||
$.post('/webGui/include/RoutingTable.php',{task:'update'},function(data){
|
||||
if (data) $('#route_list').html(data);
|
||||
timers.routeTable = setTimeout(routeTable,10000);
|
||||
});
|
||||
}
|
||||
function resetTable() {
|
||||
document.add_routes.route.value = '';
|
||||
document.add_routes.gateway.value = '';
|
||||
document.add_routes.metric.value = '';
|
||||
clearTimeout(timers.routeTable);
|
||||
routeTable();
|
||||
}
|
||||
<?if (!$tabbed):?>
|
||||
function toggleTable() {
|
||||
var tag = '#tag_table';
|
||||
var view = '#route_table';
|
||||
if ($(view).is(':visible')) {
|
||||
$(tag).removeClass('fa-chevron-up').addClass('fa-chevron-down');
|
||||
$.cookie(view,'hide',{expires:3650});
|
||||
} else {
|
||||
$(tag).removeClass('fa-chevron-down').addClass('fa-chevron-up');
|
||||
$.removeCookie(view);
|
||||
}
|
||||
$(view).toggle('slow');
|
||||
}
|
||||
$(function(){
|
||||
$('div.title').last().find('span.left').append("<span class='status vhshift'><i id='tag_table' class='fa fa-fw fa-chevron-up' style='cursor:pointer' onclick='toggleTable()'></i></span>");
|
||||
if (!$.cookie('#route_table')) $('#route_table').show(); else $('#tag_table').removeClass('fa-chevron-up').addClass('fa-chevron-down');
|
||||
routeTable();
|
||||
});
|
||||
<?else:?>
|
||||
$(function(){
|
||||
$('#route_table').show();
|
||||
routeTable();
|
||||
});
|
||||
<?endif;?>
|
||||
</script>
|
||||
<div markdown="1" id="route_table" style="display:none">
|
||||
<table class="share_status">
|
||||
<thead><tr><td>_(Protocol)_</td><td>_(Route)_</td><td>_(Gateway)_</td><td>_(Metric)_</td><td style="width:8%;text-align:center">_(Delete)_</td></tr></thead>
|
||||
<tbody id="route_list"></tbody>
|
||||
</table>
|
||||
|
||||
<div class="shade-<?=$display['theme']?>" style="margin-top:12px;padding:12px 4px;">
|
||||
<form markdown="1" name="add_routes" method="POST" action="/webGui/include/RoutingTable.php" target="progressFrame" onsubmit="setTimeout(resetTable,500)">
|
||||
_(Enter route + gateway + metric)_:
|
||||
: <input type="text" name="route" maxlength="39" value="" class="fixed" placeholder="_(IPv4/nn or IPv6/nn route)_" required>
|
||||
<input type="text" name="gateway" class="fixed" value="" list="device" placeholder="_(gateway name or address)_" required>
|
||||
<datalist id="device"><?foreach ($list as $port):?><?echo "<option value='$port'>"?><?endforeach;?></datalist>
|
||||
<input type="text" name="metric" min="1" max="9999" value="" class="trim" placeholder="1"><i class="fa fa-sort-numeric-asc"></i> *_(optional metric (lowest is preferred))_*
|
||||
|
||||
:eth_routing_table_help:
|
||||
|
||||
|
||||
: <input type="submit" name="task" value="_(Add Route)_"><input type="button" value="_(Done)_" class="lock" onclick="done()">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,4 @@
|
||||
Menu="NetworkServices:3"
|
||||
Type="xmenu"
|
||||
Title="SMB"
|
||||
Icon="icon-windows"
|
||||
@@ -0,0 +1,52 @@
|
||||
Menu="SMB:3"
|
||||
Title="Active Directory Settings"
|
||||
Tag="list-ul"
|
||||
Cond="($var['shareSMBEnabled']=='ads')"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
<form markdown="1" name="JoinOps" method="POST" action="/update.htm" target="progressFrame">
|
||||
_(AD join status)_:
|
||||
: <?=$var['joinStatus'];?>
|
||||
|
||||
_(AD domain name)_ (FQDN):
|
||||
: <input type="text" name="DOMAIN" maxlength="80" value="<?=htmlspecialchars($var['DOMAIN'])?>">
|
||||
|
||||
_(AD short domain name)_:
|
||||
: <input type="text" name="DOMAIN_SHORT" maxlength="40" value="<?=htmlspecialchars($var['DOMAIN_SHORT'])?>">
|
||||
|
||||
_(AD account login)_:
|
||||
: <input type="text" name="DOMAIN_LOGIN" maxlength="40" value="<?=htmlspecialchars($var['DOMAIN_LOGIN'])?>">
|
||||
|
||||
_(AD account password)_:
|
||||
: <input type="password" name="DOMAIN_PASSWD" maxlength="40" value="<?=htmlspecialchars($var['DOMAIN_PASSWD'])?>">
|
||||
|
||||
|
||||
: <?if ($var['joinStatus']=="Joined"):?>
|
||||
<input type="submit" name="cmdJoinDomain" value="_(Join)_" disabled><input type="submit" name="cmdLeaveDomain" value="_(Leave)_">
|
||||
<?else:?>
|
||||
<input type="submit" name="cmdJoinDomain" value="_(Join)_"><input type="submit" name="cmdLeaveDomain" value="_(Leave)_" disabled>
|
||||
<?endif;?>
|
||||
</form>
|
||||
<br>
|
||||
|
||||
<form markdown="1" name="shareOwnership" method="POST" action="/update.htm" target="progressFrame">
|
||||
_(AD initial owner)_:
|
||||
: <input type="text" name="shareInitialOwner" maxlength="40" value="<?=htmlspecialchars($var['shareInitialOwner'])?>">
|
||||
|
||||
_(AD initial group)_:
|
||||
: <input type="text" name="shareInitialGroup" maxlength="40" value="<?=htmlspecialchars($var['shareInitialGroup'])?>">
|
||||
|
||||
|
||||
: <input type="submit" name="changeShare" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
@@ -0,0 +1,43 @@
|
||||
Menu="SMB:2"
|
||||
Title="SMB Extras"
|
||||
Cond="($var['shareSMBEnabled']!='no')"
|
||||
Tag="share-alt-square"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2020, Lime Technology
|
||||
* Copyright 2020, 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.
|
||||
*/
|
||||
?>
|
||||
:smb_extra_conf_help:
|
||||
|
||||
<?
|
||||
$file = "/boot/config/smb-extra.conf";
|
||||
$text = @file_get_contents($file) ?: '';
|
||||
$text = preg_replace(["/\r\n/","/\r/"],"\n",$text);
|
||||
?>
|
||||
<script>
|
||||
$(function(){
|
||||
$('form').find('textarea').on('input change',function(){
|
||||
$(this).prop('rows',($(this).val().match(/\n/g)||[]).length+1);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame">
|
||||
<input type="hidden" name="#include" value="/webGui/include/update.file.php">
|
||||
<input type="hidden" name="#file" value="<?=$file;?>">
|
||||
_(Samba extra configuration)_:
|
||||
: <textarea spellcheck="false" cols="80" rows="<?=substr_count($text,"\n")+1?>" maxlength="2048" name="text" style="resize:none;font-family:bitstream;width:65.5%" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>><?=htmlspecialchars($text)?></textarea>
|
||||
|
||||
|
||||
: <input type="submit" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()"><?if ($var['fsState']=="Started"):?>*_(Array must be **Stopped** to change)_*<?endif;?>
|
||||
|
||||
:smb_extra_button_help:
|
||||
|
||||
</form>
|
||||
@@ -0,0 +1,36 @@
|
||||
Menu="SMB:2"
|
||||
Title="Workgroup Settings"
|
||||
Tag="sitemap"
|
||||
Cond="($var['shareSMBEnabled']=='yes')"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
<form markdown="1" name="WorkGroup" method="POST" action="/update.htm" target="progressFrame">
|
||||
_(Workgroup)_:
|
||||
: <input type="text" name="WORKGROUP" maxlength="40" value="<?=htmlspecialchars($var['WORKGROUP'])?>" class="narrow" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
|
||||
:smb_workgroup_help:
|
||||
|
||||
<?if ($var['USE_NETBIOS']=="yes"):?>
|
||||
_(Local master)_:
|
||||
: <select name="localMaster" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
<?=mk_option($var['localMaster'], "no", _('No'))?>
|
||||
<?=mk_option($var['localMaster'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:smb_local_master_help:
|
||||
|
||||
<?endif?>
|
||||
|
||||
: <input type="submit" name="changeShare" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()"><?if ($var['fsState']=="Started"):?>*_(Array must be **Stopped** to change)_*<?endif;?>
|
||||
</form>
|
||||
@@ -0,0 +1,87 @@
|
||||
Menu="SMB:1"
|
||||
Title="SMB Settings"
|
||||
Tag="windows"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
<form markdown="1" name="SMBEnable" method="POST" action="/update.htm" target="progressFrame">
|
||||
|
||||
_(Enable SMB)_:
|
||||
: <select name="shareSMBEnabled" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
<?=mk_option($var['shareSMBEnabled'], "no", _('No'))?>
|
||||
<?=mk_option($var['shareSMBEnabled'], "yes", _('Yes').' ('._('Workgroup').')')?>
|
||||
<?=mk_option($var['shareSMBEnabled'], "ads", _('Yes').' ('._('Active Directory').')')?>
|
||||
</select>
|
||||
|
||||
:smb_enable_help:
|
||||
|
||||
_(Hide "dot" files)_:
|
||||
: <select name="hideDotFiles" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
<?=mk_option($var['hideDotFiles'], "no", _('No'))?>
|
||||
<?=mk_option($var['hideDotFiles'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:smb_hide_files_help:
|
||||
|
||||
_(Enable SMB Multi Channel)_:
|
||||
: <select name="serverMultiChannel" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
<?=mk_option($var['serverMultiChannel'], "no", _('No'))?>
|
||||
<?=mk_option($var['serverMultiChannel'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:smb_multi_channel_help:
|
||||
|
||||
_(Enhanced macOS interoperability)_:
|
||||
: <select name="enableFruit" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
<?=mk_option($var['enableFruit'], "no", _('No'))?>
|
||||
<?=mk_option($var['enableFruit'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:smb_enhanced_macos_help:
|
||||
|
||||
_(Enable NetBIOS)_:
|
||||
: <select name="USE_NETBIOS" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
<?=mk_option($var['USE_NETBIOS'], "no", _('No'))?>
|
||||
<?=mk_option($var['USE_NETBIOS'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:smb_enable_netbios_help:
|
||||
|
||||
_(Enable WSD)_:
|
||||
: <select name="USE_WSD" onchange="checkWSDSettings()" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
<?=mk_option($var['USE_WSD'], "no", _('No'))?>
|
||||
<?=mk_option($var['USE_WSD'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:smb_enable_wsd_help:
|
||||
|
||||
_(WSD options [experimental])_:
|
||||
: <input type="text" name="WSD2_OPT" maxlength="80" class="narrow" value="<?=htmlspecialchars($var['WSD2_OPT'])?>" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
|
||||
:smb_wsd_options_help:
|
||||
|
||||
|
||||
: <input type="submit" name="changeShare" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()"><?if ($var['fsState']=="Started"):?>*_(Array must be **Stopped** to change)_*<?endif;?>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
function checkWSDSettings() {
|
||||
form=document.SMBEnable;
|
||||
if (form.USE_WSD.value=="yes") {
|
||||
form.WSD2_OPT.disabled=false;
|
||||
} else {
|
||||
form.WSD2_OPT.disabled=true;
|
||||
}
|
||||
}
|
||||
$(checkWSDSettings);
|
||||
</script>
|
||||
@@ -0,0 +1,4 @@
|
||||
Menu="UserPreferences"
|
||||
Type="xmenu"
|
||||
Title="Scheduler"
|
||||
Icon="icon-scheduler"
|
||||
@@ -0,0 +1,142 @@
|
||||
Menu="Disk Share"
|
||||
Title="NFS Security Settings"
|
||||
Tag="linux"
|
||||
Cond="(($var['shareNFSEnabled']!='no') && (isset($name)?array_key_exists($name,$sec_nfs):0))"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2012-2022, 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$width = [123,300];
|
||||
?>
|
||||
:nfs_security_help:
|
||||
|
||||
<div class="clone1">
|
||||
<span class="clone">_(Read settings from)_</span><i class="fa fa-arrow-left fa-fw"></i>
|
||||
<span class="wrap"><select name="readnfs" class="clone" onchange="toggleButton('readnfs',false)">
|
||||
<option disabled selected>_(select)_...</option>
|
||||
<?
|
||||
if (isset($disks[$name])) {
|
||||
foreach (array_filter($disks,'clone_list') as $list) if ($list['name']!=$name) echo mk_option("", $list['name'], _(my_disk($list['name']),3));
|
||||
} else {
|
||||
foreach ($shares as $list) if ($list['name']!=$name) echo mk_option("", $list['name'], compress($list['name']));
|
||||
}
|
||||
?>
|
||||
</select></span><input type="button" id="readnfs" value="_(Read)_" class="clone" onclick="readNFS()" disabled>
|
||||
</div>
|
||||
<div class="clone2">
|
||||
<span class="clone">_(Write settings to)_</span><i class="fa fa-arrow-right fa-fw"></i>
|
||||
<span class="wrap"><select id="nfs1" name="writenfs" multiple="multiple" style="display:none" onchange="toggleButton('writenfs',this.id)">
|
||||
<?
|
||||
$rows = [];
|
||||
if (isset($disks[$name])) {
|
||||
foreach (array_filter($disks,'clone_list') as $list) if ($list['name']!=$name) $rows[] = mk_option("", $list['name'], _(my_disk($list['name']),3));
|
||||
} else {
|
||||
foreach ($shares as $list) if ($list['name']!=$name) $rows[] = mk_option("", $list['name'], compress($list['name']));
|
||||
}
|
||||
if ($rows) echo "<option>("._('All').")</option>";
|
||||
foreach ($rows as $row) echo $row;
|
||||
?>
|
||||
</select></span><input type="button" id="writenfs" value="_(Write)_" class="clone" onclick="writeNFS()" disabled>
|
||||
</div>
|
||||
|
||||
<form markdown="1" name="nfs_edit" method="POST" action="/update.htm" target="progressFrame" onchange="toggleButton('writenfs',true);$('#nfs1').dropdownchecklist('disable')">
|
||||
<input type="hidden" name="shareName" value="<?=htmlspecialchars($name)?>">
|
||||
|
||||
_(Share name)_:
|
||||
: <?=htmlspecialchars($name)?>
|
||||
|
||||
_(Export)_:
|
||||
: <select name="shareExportNFS">
|
||||
<?=mk_option($sec_nfs[$name]['export'], "-", _('No'));?>
|
||||
<?=mk_option($sec_nfs[$name]['export'], "e", _('Yes'));?>
|
||||
</select>
|
||||
|
||||
_(Security)_:
|
||||
: <select name="shareSecurityNFS">
|
||||
<?=mk_option($sec_nfs[$name]['security'], "public", _('Public'));?>
|
||||
<?=mk_option($sec_nfs[$name]['security'], "secure", _('Secure'));?>
|
||||
<?=mk_option($sec_nfs[$name]['security'], "private", _('Private'));?>
|
||||
</select>
|
||||
|
||||
|
||||
: <input type="submit" name="changeShareSecurityNFS" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
|
||||
<?if ($sec_nfs[$name]['security']=='private'):?>
|
||||
<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="submit" name="changeShareAccessNFS" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
<?endif;?>
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
initDropdownNFS(false);
|
||||
if ($.cookie('hostList')!=null) {
|
||||
var host = $('input[name="shareHostListNFS"]');
|
||||
host.val($.cookie('hostList'));
|
||||
setTimeout(function(){host.trigger('change');},100);
|
||||
$.removeCookie('hostList');
|
||||
}
|
||||
<?if ($tabbed):?>
|
||||
<?$path=='Shares/Share' ? $t=2 : $t=1;?>
|
||||
$('#tab<?=$t?>').bind({click:function(){initDropdownNFS(true);}});
|
||||
<?endif;?>
|
||||
});
|
||||
function initDropdownNFS(reset) {
|
||||
if (reset) {
|
||||
$('#nfs1').dropdownchecklist('destroy');
|
||||
}
|
||||
$("#nfs1").dropdownchecklist({firstItemChecksAll:true, emptyText:"_(select)_...", width:<?=$width[0]?>, explicitClose:"..._(close)_"});
|
||||
}
|
||||
function readNFS() {
|
||||
var form = document.nfs_edit;
|
||||
var name = $('select[name="readnfs"]').val();
|
||||
$.get('/webGui/include/ProtocolData.php',{protocol:'nfs',name:name},function(json) {
|
||||
var data = $.parseJSON(json);
|
||||
form.shareExportNFS.value = data.export;
|
||||
form.shareSecurityNFS.value = data.security;
|
||||
if (data.hostList != '') $.cookie('hostList',data.hostList);
|
||||
$(form).find('select').trigger('change');
|
||||
});
|
||||
}
|
||||
function writeNFS(data,n,i) {
|
||||
if (data) {
|
||||
if (n<i) {
|
||||
$.post('/update.htm',data[n], function(){setTimeout(function(){writeNFS(data,++n,i);},3000);});
|
||||
} else {
|
||||
toggleButton('writenfs',false);
|
||||
$('div.spinner.fixed').hide();
|
||||
}
|
||||
} else {
|
||||
var data = [], i = 0;
|
||||
$('select#nfs1 option').map(function(i) {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(_(All)_)') {
|
||||
data[i] = {};
|
||||
data[i]['shareName'] = $(this).val();
|
||||
data[i]['shareExportNFS'] = '<?=addslashes(htmlspecialchars($sec_nfs[$name]['export']))?>';
|
||||
data[i]['shareSecurityNFS'] = '<?=addslashes(htmlspecialchars($sec_nfs[$name]['security']))?>';
|
||||
data[i]['changeShareSecurityNFS'] = 'Apply';
|
||||
i++;
|
||||
}
|
||||
});
|
||||
toggleButton('writenfs',true);
|
||||
$('div.spinner.fixed').show('slow');
|
||||
writeNFS(data,0,i);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,318 @@
|
||||
Menu="Disk Share Flash"
|
||||
Title="SMB Security Settings"
|
||||
Tag="windows"
|
||||
Cond="(($var['shareSMBEnabled']!='no') && (isset($name)?array_key_exists($name,$sec):0))"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
require_once "$docroot/webGui/include/InputSecurity.php";
|
||||
|
||||
$width = [123,300];
|
||||
?>
|
||||
:smb_security_help:
|
||||
|
||||
<div class="clone1">
|
||||
<span class="clone">_(Read settings from)_</span><i class="fa fa-arrow-left fa-fw"></i>
|
||||
<span class="wrap"><select name="readsmb" class="clone" onchange="toggleButton('readsmb',false)">
|
||||
<option disabled selected>_(select)_...</option>
|
||||
<?
|
||||
if (isset($disks[$name])) {
|
||||
foreach (array_filter($disks,'clone_list') as $list) if ($list['name']!=$name) echo mk_option("", $list['name'], _(my_disk($list['name']),3));
|
||||
} else {
|
||||
foreach ($shares as $list) if ($list['name']!=$name) echo mk_option("", $list['name'], compress($list['name']));
|
||||
}
|
||||
?>
|
||||
</select></span><input type="button" id="readsmb" value="_(Read)_" class="clone" onclick="readSMB()" disabled>
|
||||
</div>
|
||||
<div class="clone2">
|
||||
<span class="clone">_(Write settings to)_</span><i class="fa fa-arrow-right fa-fw"></i>
|
||||
<span class="wrap"><select id="smb1" name="writesmb" multiple="multiple" style="display:none" onchange="toggleButton('writesmb',this.id)">
|
||||
<?
|
||||
$rows = [];
|
||||
if (isset($disks[$name])) {
|
||||
foreach (array_filter($disks,'clone_list') as $list) if ($list['name']!=$name) $rows[] = mk_option("", $list['name'], _(my_disk($list['name']),3));
|
||||
} else {
|
||||
foreach ($shares as $list) if ($list['name']!=$name) $rows[] = mk_option("", $list['name'], compress($list['name']));
|
||||
}
|
||||
if ($rows) echo "<option>("._('All').")</option>";
|
||||
foreach ($rows as $row) echo $row;
|
||||
?>
|
||||
</select></span><input type="button" id="writesmb" value="_(Write)_" class="clone" onclick="writeSMB()" disabled>
|
||||
</div>
|
||||
|
||||
<form markdown="1" name="smb_edit" method="POST" action="/update.htm" target="progressFrame" onchange="toggleButton('writesmb',true);$('#smb1').dropdownchecklist('disable')">
|
||||
<input type="hidden" name="shareName" value="<?=htmlspecialchars($name)?>">
|
||||
|
||||
_(Share name)_:
|
||||
: <?=htmlspecialchars($name)?>
|
||||
|
||||
<?if (($name=='flash')||($var['enableFruit']!='yes')):?>
|
||||
_(Export)_:
|
||||
: <select name="shareExport">
|
||||
<?=mk_option($sec[$name]['export'], "-", _('No'))?>
|
||||
<?=mk_option($sec[$name]['export'], "e", _('Yes'))?>
|
||||
<?=mk_option($sec[$name]['export'], "eh", _('Yes (hidden)'))?>
|
||||
</select>
|
||||
|
||||
:smb_export_help:
|
||||
|
||||
<input type="hidden" name="shareVolsizelimit" value="">
|
||||
<?else:?>
|
||||
_(Export)_:
|
||||
: <select name="shareExport" onchange="checkShareSettingsSMB(this.form)">
|
||||
<?=mk_option($sec[$name]['export'], "-", _('No'))?>
|
||||
<?=mk_option($sec[$name]['export'], "e", _('Yes'))?>
|
||||
<?=mk_option($sec[$name]['export'], "eh", _('Yes (hidden)'))?>
|
||||
<?=mk_option($sec[$name]['export'], "et", _('Yes/Time Machine'))?>
|
||||
<?=mk_option($sec[$name]['export'], "eth", _('Yes/Time Machine (hidden)'))?>
|
||||
</select>
|
||||
|
||||
:smb_export_help:
|
||||
|
||||
_(Time Machine volume size limit)_:
|
||||
: <input type="text" name="shareVolsizelimit" maxlen="20" value="<?=$sec[$name]['volsizelimit']?>"> MB
|
||||
|
||||
:smb_time_machine_volume_help:
|
||||
|
||||
<?endif;?>
|
||||
<?if ($name!='flash'):?>
|
||||
_(Case-sensitive names)_:
|
||||
: <select name="shareCaseSensitive">
|
||||
<?=mk_option($sec[$name]['caseSensitive'], "auto", _("Auto"))?>
|
||||
<?=mk_option($sec[$name]['caseSensitive'], "yes", _("Yes"))?>
|
||||
<?=mk_option($sec[$name]['caseSensitive'], "forced", _("Force lower"))?>
|
||||
</select>
|
||||
|
||||
:smb_case_sensitive_names_help:
|
||||
|
||||
<?endif;?>
|
||||
_(Security)_:
|
||||
: <select name="shareSecurity">
|
||||
<?=mk_option($sec[$name]['security'], "public", _('Public'))?>
|
||||
<?=mk_option($sec[$name]['security'], "secure", _('Secure'))?>
|
||||
<?=mk_option($sec[$name]['security'], "private", _('Private'))?>
|
||||
</select>
|
||||
|
||||
:smb_security_modes_help:
|
||||
|
||||
|
||||
: <input type="submit" name="changeShareSecurity" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
|
||||
<?if ($sec[$name]['security']=='secure'):?>
|
||||
<div class="title nocontrol"><dt>_(SMB)_ _(User Access)_</dt><i>_(Guests have **read-only** access)_.</i></div>
|
||||
|
||||
:smb_secure_access_help:
|
||||
|
||||
<div class="clone1">
|
||||
<span class="clone">_(Read settings from)_</span><i class="fa fa-arrow-left fa-fw"></i>
|
||||
<span class="wrap"><select name="readusersmb" class="clone" onchange="toggleButton('readusersmb',false)">
|
||||
<option disabled selected>_(select)_...</option>
|
||||
<?
|
||||
if (isset($disks[$name])) {
|
||||
foreach (array_filter($disks,'clone_list') as $list) if ($list['name']!=$name && $sec[$list['name']]['security']=='secure') echo mk_option("", $list['name'], _(my_disk($list['name']),3));
|
||||
} else {
|
||||
foreach ($shares as $list) if ($list['name']!=$name && $sec[$list['name']]['security']=='secure') echo mk_option("", $list['name'], compress($list['name']));
|
||||
}
|
||||
?>
|
||||
</select></span><input type="button" id="readusersmb" value="_(Read)_" class="clone" onclick="readUserSMB()" disabled>
|
||||
</div>
|
||||
<div class="clone2">
|
||||
<span class="clone">_(Write settings to)_</span><i class="fa fa-arrow-right fa-fw"></i>
|
||||
<span class="wrap"><select id="smb2" name="writeusersmb" multiple="multiple" style="display:none" onchange="toggleButton('writeusersmb',this.id)">
|
||||
<?
|
||||
$rows = [];
|
||||
if (isset($disks[$name])) {
|
||||
foreach (array_filter($disks,'clone_list') as $list) if ($list['name']!=$name && $sec[$list['name']]['security']=='secure') $rows[] = mk_option("", $list['name'], _(my_disk($list['name']),3));
|
||||
} else {
|
||||
foreach ($shares as $list) if ($list['name']!=$name && $sec[$list['name']]['security']=='secure') $rows[] = mk_option("", $list['name'], compress($list['name']));
|
||||
}
|
||||
if ($rows) echo "<option>("._('All').")</option>";
|
||||
foreach ($rows as $row) echo $row;
|
||||
?>
|
||||
</select></span><input type="button" id="writeusersmb" value="_(Write)_" class="clone" onclick="writeUserSMB()" disabled>
|
||||
</div>
|
||||
|
||||
<form markdown="1" name="smb_user_edit" method="POST" action="/update.htm" target="progressFrame" onchange="toggleButton('writeusersmb',true);$('#smb2').dropdownchecklist('disable')">
|
||||
<input type="hidden" name="shareName" value="<?=htmlspecialchars($name)?>">
|
||||
<?input_secure_users($sec)?>
|
||||
|
||||
|
||||
: <input type="submit" name="changeShareAccess" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
|
||||
<?elseif ($sec[$name]['security']=='private'):?>
|
||||
<div class="title nocontrol"><dt>_(SMB)_ _(User Access)_</dt><i>_(Guests have **no** access)_.</i></div>
|
||||
|
||||
:smb_private_access_help:
|
||||
|
||||
<div class="clone1">
|
||||
<span class="clone">_(Read settings from)_</span><i class="fa fa-arrow-left fa-fw"></i>
|
||||
<span class="wrap"><select name="readusersmb" class="clone" onchange="toggleButton('readusersmb',false)">
|
||||
<option disabled selected>_(select)_...</option>
|
||||
<?
|
||||
if (isset($disks[$name])) {
|
||||
foreach (array_filter($disks,'clone_list') as $list) if ($list['name']!=$name && $sec[$list['name']]['security']=='private') echo mk_option("", $list['name'], _(my_disk($list['name']),3));
|
||||
} else {
|
||||
foreach ($shares as $list) if ($list['name']!=$name && $sec[$list['name']]['security']=='private') echo mk_option("", $list['name'], compress($list['name']));
|
||||
}
|
||||
?>
|
||||
</select></span><input type="button" id="readusersmb" value="_(Read)_" class="clone" onclick="readUserSMB()" disabled>
|
||||
</div>
|
||||
<div class="clone2">
|
||||
<span class="clone">_(Write settings to)_</span><i class="fa fa-arrow-right fa-fw"></i>
|
||||
<span class="wrap"><select id="smb2" name="writeusersmb" multiple="multiple" style="display:none" onchange="toggleButton('writeusersmb',this.id)">
|
||||
<?
|
||||
$rows = [];
|
||||
if (isset($disks[$name])) {
|
||||
foreach (array_filter($disks,'clone_list') as $list) if ($list['name']!=$name && $sec[$list['name']]['security']=='private') $rows[] = mk_option("", $list['name'], _(my_disk($list['name']),3));
|
||||
} else {
|
||||
foreach ($shares as $list) if ($list['name']!=$name && $sec[$list['name']]['security']=='private') $rows[] = mk_option("", $list['name'], compress($list['name']));
|
||||
}
|
||||
if ($rows) echo "<option>("._('All').")</option>";
|
||||
foreach ($rows as $row) echo $row;
|
||||
?>
|
||||
</select></span><input type="button" id="writeusersmb" value="_(Write)_" class="clone" onclick="writeUserSMB()" disabled>
|
||||
</div>
|
||||
|
||||
<form markdown="1" name="smb_user_edit" method="POST" action="/update.htm" target="progressFrame" onchange="toggleButton('writeusersmb',true);$('#smb2').dropdownchecklist('disable')">
|
||||
<input type="hidden" name="shareName" value="<?=htmlspecialchars($name)?>">
|
||||
<?input_private_users($sec)?>
|
||||
|
||||
|
||||
: <input type="submit" name="changeShareAccess" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
<?endif;?>
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
checkShareSettingsSMB(document.smb_edit);
|
||||
initDropdownSMB(false);
|
||||
<?if ($tabbed):?>
|
||||
$('#tab'+$('input[name$="tabs"]').length).bind({click:function(){initDropdownSMB(true);}});
|
||||
<?endif;?>
|
||||
<?if (count($users)==1):?>
|
||||
toggleButton('readusersmb',true);
|
||||
toggleButton('writeusersmb',true);
|
||||
$('#smb2').dropdownchecklist('disable');
|
||||
<?endif;?>
|
||||
});
|
||||
function checkShareSettingsSMB(form) {
|
||||
form.shareVolsizelimit.disabled = (form.shareExport.value.indexOf("et") == -1);
|
||||
}
|
||||
function initDropdownSMB(reset) {
|
||||
if (reset) {
|
||||
$('#smb1').dropdownchecklist('destroy');
|
||||
$('#smb2').dropdownchecklist('destroy');
|
||||
}
|
||||
$("#smb1").dropdownchecklist({firstItemChecksAll:true, emptyText:"_(select)_...", width:<?=$width[0]?>, explicitClose:"..._(close)_"});
|
||||
$("#smb2").dropdownchecklist({firstItemChecksAll:true, emptyText:"_(select)_...", width:<?=$width[0]?>, explicitClose:"..._(close)_"});
|
||||
}
|
||||
function readSMB() {
|
||||
var form = document.smb_edit;
|
||||
var name = $('select[name="readsmb"]').val();
|
||||
$.get('/webGui/include/ProtocolData.php',{protocol:'smb',name:name},function(json) {
|
||||
var data = $.parseJSON(json);
|
||||
form.shareExport.value = data.export;
|
||||
form.shareFruit.value = data.fruit;
|
||||
form.shareSecurity.value = data.security;
|
||||
});
|
||||
$(form).find('select').trigger('change');
|
||||
}
|
||||
function writeSMB(data,n,i) {
|
||||
if (data) {
|
||||
if (n<i) {
|
||||
$.post('/update.htm',data[n], function(){setTimeout(function(){writeSMB(data,++n,i);},3000);});
|
||||
} else {
|
||||
toggleButton('writesmb',false);
|
||||
$('div.spinner.fixed').hide();
|
||||
}
|
||||
} else {
|
||||
var data = [], i = 0;
|
||||
$('select#smb1 option').map(function() {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(_(All)_)') {
|
||||
data[i] = {};
|
||||
data[i]['shareName'] = $(this).val();
|
||||
data[i]['shareExport'] = '<?=addslashes(htmlspecialchars($sec[$name]['export']))?>';
|
||||
data[i]['shareFruit'] = '<?=addslashes(htmlspecialchars($sec[$name]['fruit']))?>';
|
||||
data[i]['shareSecurity'] = '<?=addslashes(htmlspecialchars($sec[$name]['security']))?>';
|
||||
data[i]['changeShareSecurity'] = 'Apply';
|
||||
i++;
|
||||
}
|
||||
});
|
||||
toggleButton('writesmb',true);
|
||||
$('div.spinner.fixed').show('slow');
|
||||
writeSMB(data,0,i);
|
||||
}
|
||||
}
|
||||
function readUserSMB() {
|
||||
var form = document.smb_user_edit;
|
||||
var name = $('select[name="readusersmb"]').val();
|
||||
var users = {};
|
||||
<?
|
||||
foreach ($users as $user) {
|
||||
if ($user['name'] == "root") continue;
|
||||
echo "users['{$user['name']}'] = {$user['idx']};\n";
|
||||
}
|
||||
?>
|
||||
$.get('/webGui/include/ProtocolData.php',{protocol:'smb',name:name},function(json) {
|
||||
var data = $.parseJSON(json);
|
||||
var readList = data.readList.split(',');
|
||||
var writeList = data.writeList.split(',');
|
||||
$(form).find('select[name^="userAccess."]').each(function(){$(this).val('no-access');});
|
||||
for (var i=0; i < readList.length; i++) $(form).find('select[name="userAccess.'+users[readList[i]]+'"]').val('read-only');
|
||||
for (var i=0; i < writeList.length; i++) $(form).find('select[name="userAccess.'+users[writeList[i]]+'"]').val('read-write');
|
||||
});
|
||||
$(form).find('select').trigger('change');
|
||||
}
|
||||
function writeUserSMB(data,n,i) {
|
||||
if (data) {
|
||||
if (n<i) {
|
||||
$.post('/update.htm',data[n], function(){setTimeout(function(){writeUserSMB(data,++n,i);},3000);});
|
||||
} else {
|
||||
toggleButton('writeusersmb',false);
|
||||
$('div.spinner.fixed').hide();
|
||||
}
|
||||
} else {
|
||||
var data = [], i = 0;
|
||||
$('select#smb2 option').map(function() {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(_(All)_)') {
|
||||
data[i] = {};
|
||||
data[i]['shareName'] = $(this).val();
|
||||
data[i]['userAccess.0'] = 'no-access';
|
||||
<?
|
||||
$read_list = explode(",", $sec[$name]['readList']);
|
||||
$write_list = explode(",", $sec[$name]['writeList']);
|
||||
foreach ($users as $user) {
|
||||
if ($user['name'] == "root") continue;
|
||||
$idx = $user['idx'];
|
||||
$userAccess = null;
|
||||
if ($sec[$name]['security']=='secure') {
|
||||
$userAccess = in_array($user['name'], $write_list) ? "read-write" : "read-only";
|
||||
} elseif ($sec[$name]['security'] == 'private') {
|
||||
$userAccess = in_array($user['name'], $write_list) ? "read-write" : (in_array($user['name'], $read_list) ? "read-only" : "no-access");
|
||||
}
|
||||
if ($userAccess) echo "data[i]['userAccess.$idx'] = '$userAccess';\n";
|
||||
}
|
||||
?>
|
||||
data[i]['changeShareAccess'] = 'Apply';
|
||||
i++;
|
||||
}
|
||||
});
|
||||
toggleButton('writeusersmb',true);
|
||||
$('div.spinner.fixed').show('slow');
|
||||
writeUserSMB(data,0,i);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,134 @@
|
||||
Menu="Device:2 New:2"
|
||||
Title="Self-Test"
|
||||
Tag="wrench"
|
||||
Cond="strpos(_var($disks[$name],'status'),'_NP')===false"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$date = date('Ymd-Hi');
|
||||
$file = _var($disk,'id','no-id')."-$date.txt";
|
||||
$zip = str_replace(' ','_',strtolower(_var($var,'NAME','tower')))."-smart-$date.zip";
|
||||
$long = !isset($disks[$name]['spindownDelay']) || _var($disks[$name],'spindownDelay')==0 || (_var($disks[$name],'spindownDelay')==-1 && _var($var,'spindownDelay')==0);
|
||||
?>
|
||||
_(Download SMART report)_:
|
||||
: <input type='button' value="_(Download)_" onclick='saveSMART()'>
|
||||
|
||||
_(SMART self-test history)_:
|
||||
: <input type="button" value="_(Show)_" id="toggle_log" onclick="selftestLog()">
|
||||
|
||||
:selftest_history_help:
|
||||
|
||||
<pre id="selftest" style="display:none"></pre>
|
||||
|
||||
_(SMART error log)_:
|
||||
: <input type="button" value="_(Show)_" id="toggle_error" onclick="errorLog()">
|
||||
|
||||
:selftest_error_log_help:
|
||||
|
||||
<pre id="errorlog" style="display:none"></pre>
|
||||
|
||||
_(SMART short self-test)_:
|
||||
: <input type='button' value="_(Start)_" id='short_test' onclick="startShortTest()">
|
||||
|
||||
:selftest_short_test_help:
|
||||
|
||||
_(SMART extended self-test)_:
|
||||
: <input type='button' value="_(Start)_" id='long_test' onclick="startLongTest()"<?=$long ? ">" : " disabled> _(Disable **Spin down delay** to run a SMART extended self-test)_"?>
|
||||
|
||||
:selftest_long_test_help:
|
||||
|
||||
_(Last SMART test result)_:
|
||||
: <span id="test_result"><i class='fa fa-circle-o-notch fa-spin fa-fw'></i></span>
|
||||
|
||||
:selftest_result_help:
|
||||
|
||||
<script>
|
||||
function cleanUp() {
|
||||
if (document.hasFocus()) {
|
||||
$('input[value="_(Downloading)_..."]').val("_(Download)_").prop('disabled',false);
|
||||
$.post('/webGui/include/Download.php',{cmd:'delete',file:'<?=addslashes(htmlspecialchars($file))?>'});
|
||||
$.post('/webGui/include/Download.php',{cmd:'delete',file:'<?=addslashes(htmlspecialchars($zip))?>'});
|
||||
} else {
|
||||
setTimeout(cleanUp,4000);
|
||||
}
|
||||
}
|
||||
function saveSMART() {
|
||||
$('input[value="_(Download)_"]').val('_(Downloading)_...').prop('disabled',true);
|
||||
$.post('/webGui/include/SmartInfo.php',{cmd:'save',port:'<?=$dev?>',name:'<?=$name?>',file:'<?=addslashes(htmlspecialchars($file))?>'}, function() {
|
||||
$.post('/webGui/include/Download.php',{cmd:'save',source:'<?=addslashes(htmlspecialchars($file))?>',file:'<?=addslashes(htmlspecialchars($zip))?>'},function(zip) {
|
||||
location = zip;
|
||||
setTimeout(cleanUp,4000);
|
||||
});
|
||||
});
|
||||
}
|
||||
function testUpdate(init) {
|
||||
$.post('/webGui/include/SmartInfo.php',{cmd:'update',port:'<?=$dev?>',name:'<?=$name?>',csrf:'<?=$var['csrf_token']?>'},function(data) {
|
||||
$('#test_result').html(data);
|
||||
if (data.indexOf('%')>=0) {
|
||||
if ($('#smart_selftest').length) {
|
||||
$('#smart_selftest').html('<i class="fa fa-camera"></i> _(SMART self-test in progress)_...');
|
||||
}
|
||||
if (!init) timers.testUpdate = setTimeout(testUpdate,3000);
|
||||
} else {
|
||||
if ($('#smart_selftest').length) $('#smart_selftest').html('');
|
||||
$('#short_test').val("_(Start)_");
|
||||
$('#long_test').val("_(Start)_");
|
||||
if (!init) {
|
||||
$.removeCookie('test.<?=$dev?>');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function selftestLog() {
|
||||
$('#selftest').toggle('slow');
|
||||
var text = $('#toggle_log').val()=="_(Show)_" ? "_(Hide)_" : "_(Show)_";
|
||||
$('#toggle_log').val(text);
|
||||
}
|
||||
function errorLog() {
|
||||
$('#errorlog').toggle('slow');
|
||||
var text = $('#toggle_error').val()=="_(Show)_" ? "_(Hide)_" : "_(Show)_";
|
||||
$('#toggle_error').val(text);
|
||||
}
|
||||
function startShortTest() {
|
||||
if ($('#short_test').val()=="_(Start)_") {
|
||||
$('#short_test').val("_(Stop)_");
|
||||
$('#long_test').attr('disabled','disabled');
|
||||
$.cookie('test.<?=$dev?>','short',{expires:365});
|
||||
$.post('/webGui/include/SmartInfo.php',{cmd:'short',port:'<?=$dev?>',name:'<?=$name?>'},function(){timers.testUpdate = setTimeout(testUpdate,0);});
|
||||
} else {
|
||||
clearTimeout(timers.testUpdate);
|
||||
$.removeCookie('test.<?=$dev?>');
|
||||
$.post('/webGui/include/SmartInfo.php',{cmd:'stop',port:'<?=$dev?>',name:'<?=$name?>'},function(){setTimeout(testUpdate,0);});
|
||||
}
|
||||
}
|
||||
function startLongTest() {
|
||||
if ($('#long_test').val()=="_(Start)_") {
|
||||
$('#long_test').val("_(Stop)_");
|
||||
$('#short_test').attr('disabled','disabled');
|
||||
$.cookie('test.<?=$dev?>','long',{expires:365});
|
||||
$.post('/webGui/include/SmartInfo.php',{cmd:'long',port:'<?=$dev?>',name:'<?=$name?>'},function(){timers.testUpdate = setTimeout(testUpdate,0);});
|
||||
} else {
|
||||
clearTimeout(timers.testUpdate);
|
||||
$.removeCookie('test.<?=$dev?>');
|
||||
$.post('/webGui/include/SmartInfo.php',{cmd:'stop',port:'<?=$dev?>',name:'<?=$name?>'},function(){setTimeout(testUpdate,0);});
|
||||
}
|
||||
}
|
||||
$(function() {
|
||||
var smarttest = $.cookie('test.<?=$dev?>');
|
||||
testUpdate(smarttest===undefined);
|
||||
if (smarttest !== undefined) $('#'+smarttest+'_test').val("_(Stop)_").removeAttr('disabled');
|
||||
$.post('/webGui/include/SmartInfo.php',{cmd:'selftest',port:'<?=$dev?>',name:'<?=$name?>'},function(data){$('#selftest').html(data);});
|
||||
$.post('/webGui/include/SmartInfo.php',{cmd:'errorlog',port:'<?=$dev?>',name:'<?=$name?>'},function(data){$('#errorlog').html(data);});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,4 @@
|
||||
Menu="Tasks:4"
|
||||
Type="xmenu"
|
||||
Tabs="false"
|
||||
Code="e924"
|
||||
@@ -0,0 +1,80 @@
|
||||
Type="xmenu"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
* Copyright 2012-2021, 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 clone_list($disk) {
|
||||
global $pools;
|
||||
return strpos($disk['status'],'_NP')===false && ($disk['type']=='Data' || in_array($disk['name'],$pools));
|
||||
}
|
||||
if ($name) {
|
||||
$refs = []; $n = $i = 0;
|
||||
// Natural sorting of share names
|
||||
uksort($shares,'strnatcasecmp');
|
||||
foreach ($shares as $ref) {
|
||||
$sname = $ref['name'];
|
||||
$refs[] = $sname;
|
||||
if ($sname==$name) $i = $n;
|
||||
$n++;
|
||||
}
|
||||
$end = count($refs)-1;
|
||||
if ($end >= 0) {
|
||||
$prev = urlencode($i>0 ? $refs[$i-1] : $refs[$end]);
|
||||
$next = urlencode($i<$end ? $refs[$i+1] : $refs[0]);
|
||||
} else {
|
||||
$prev = $next = '';
|
||||
}
|
||||
} else {
|
||||
$tabbed = false;
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
div.clone1{position:absolute;right:10px;margin-top:0}
|
||||
div.clone2{position:absolute;right:10px;margin-top:48px}
|
||||
span.input{display:inline-block;width:330px}
|
||||
<?if ($themes1):?>
|
||||
span.wrap{display:inline-block;width:128px}
|
||||
select.clone{min-width:123px;max-width:123px;margin-right:0}
|
||||
<?else:?>
|
||||
span.wrap{display:inline-block;width:150px}
|
||||
select.clone{min-width:145px;max-width:145px;margin-right:0}
|
||||
<?endif;?>
|
||||
input.clone{margin-left:8px;margin-right:0}
|
||||
span.clone{margin-right:4px}
|
||||
</style>
|
||||
<script>
|
||||
function toggleButton(button,id) {
|
||||
var disabled = true;
|
||||
switch (id) {
|
||||
case false:
|
||||
case true:
|
||||
disabled = id;
|
||||
break;
|
||||
default:
|
||||
$('select#'+id+' option').each(function(){if ($(this).prop('selected')==true) disabled = false;});
|
||||
}
|
||||
$('input#'+button).prop('disabled',disabled);
|
||||
}
|
||||
|
||||
<?if ($name):?>
|
||||
var ctrl = '<span class="ctrl1 status <?=$tabbed?'vhshift':'vshift'?>"><a href="/Shares/Share?name=<?=$prev?>" title="_(previous user share)_"><button type="button" style="margin-right:4px"><i class="fa fa-chevron-left fa-fw"></i></button></a><a href="/Shares/Share?name=<?=$next?>" title="_(next user share)_"><button type="button"><i class="fa fa-chevron-right fa-fw"></i></button></a></span>';
|
||||
|
||||
$(function() {
|
||||
<?if ($tabbed):?>
|
||||
$('.tabs').append(ctrl);
|
||||
<?else:?>
|
||||
$('div[class=title]:first').append(ctrl);
|
||||
<?endif;?>
|
||||
});
|
||||
<?endif;?>
|
||||
</script>
|
||||
@@ -0,0 +1,598 @@
|
||||
Menu="Share:1"
|
||||
Title="Share Settings"
|
||||
Tag="share-alt-square"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$width = [123,300];
|
||||
|
||||
if ($name == "") {
|
||||
// default values when adding new share
|
||||
$share = ["nameOrig" => "",
|
||||
"name" => "",
|
||||
"comment" => "",
|
||||
"allocator" => "highwater",
|
||||
"floor" => "",
|
||||
"splitLevel" => "",
|
||||
"include" => "",
|
||||
"exclude" => "",
|
||||
"useCache" => "no",
|
||||
"cachePool" => "",
|
||||
"cow" => "auto"
|
||||
];
|
||||
} elseif (array_key_exists($name, $shares)) {
|
||||
// edit existing share
|
||||
$share = $shares[$name];
|
||||
} else {
|
||||
// handle share deleted case
|
||||
echo "<p class='notice'>"._('Share')." '".htmlspecialchars($name)."' "._('has been deleted').".</p><input type='button' value=\""._('Done')."\" onclick='done()'>";
|
||||
return;
|
||||
}
|
||||
// Check for non existent pool device
|
||||
if ($share['cachePool'] && !in_array($share['cachePool'],$pools)) $share['useCache'] = "no";
|
||||
|
||||
function globalInclude($name) {
|
||||
global $var;
|
||||
return substr($name,0,4)=='disk' && (!$var['shareUserInclude'] || in_array($name,explode(',',$var['shareUserInclude'])));
|
||||
}
|
||||
function sanitize(&$val) {
|
||||
$data = explode('.',str_replace([' ',','],['','.'],$val));
|
||||
$last = array_pop($data);
|
||||
$val = count($data) ? implode($data).".$last" : $last;
|
||||
}
|
||||
function presetSpace($val) {
|
||||
global $disks,$shares,$name,$pools,$display;
|
||||
if (!$val or strcasecmp($val,'NaN')==0) return;
|
||||
sanitize($val);
|
||||
$small = [];
|
||||
foreach (data_filter($disks) as $disk) $small[] = _var($disk,'fsSize');
|
||||
$fsSize[""] = min(array_filter($small));
|
||||
foreach ($pools as $pool) $fsSize[$pool] = _var($disks[$pool],'fsSize',0);
|
||||
$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);
|
||||
}
|
||||
[$dot,$comma] = str_split(_var($display,'number','.,'));
|
||||
return $size>0 ? number_format($size,$size-floor($size)?1:0,$dot,$comma).' '.$unit : '';
|
||||
}
|
||||
function fsSize() {
|
||||
global $disks,$pools;
|
||||
$fsSize = $small = [];
|
||||
foreach (data_filter($disks) as $disk) $small[] = _var($disk,'fsSize');
|
||||
$fsSize[] = '"":"'.min(array_filter($small)).'"';
|
||||
foreach ($pools as $pool) $fsSize[] = '"'.$pool.'":"'._var($disks[$pool],'fsSize',0).'"';
|
||||
return implode(',',$fsSize);
|
||||
}
|
||||
function fsType() {
|
||||
global $disks,$pools;
|
||||
$fsType = [];
|
||||
foreach ($pools as $pool) $fsType[] = '"'.$pool.'":"'.str_replace('luks:','',_var($disks[$pool],'fsType')).'"';
|
||||
return implode(',',$fsType);
|
||||
}
|
||||
function primary() {
|
||||
global $share;
|
||||
return $share['useCache']=='no' ? '' : $share['cachePool'];
|
||||
}
|
||||
function secondary() {
|
||||
global $share;
|
||||
return in_array($share['useCache'],['no','only']) ? '0' : '1';
|
||||
}
|
||||
function direction() {
|
||||
global $share;
|
||||
return $share['useCache']=='prefer' ? '1' : '0';
|
||||
}
|
||||
// global shares include/exclude
|
||||
$myDisks = array_filter(array_diff(array_keys(array_filter($disks,'my_disks')), explode(',',$var['shareUserExclude'])), 'globalInclude');
|
||||
?>
|
||||
<style>
|
||||
div.shade-white{background-color:#ededed;margin-top:10px;padding:8px 0 3px 0}
|
||||
div.shade-black{background-color:#212121;margin-top:10px;padding:8px 0 3px 0}
|
||||
div.shade-azure{background-color:#edeaef;margin-top:10px;padding:8px 0 3px 0}
|
||||
div.shade-gray{background-color:#121510;margin-top:10px;padding:8px 0 3px 0}
|
||||
#s1,#s2,#s3,#s4,#s5,#autosize,.empty,.full2,#zfs-name{display:none}
|
||||
i.fa-info.i{margin-right:10px}
|
||||
<?if ($themes1):?>
|
||||
form[name=share_edit]{margin-top:-20px}
|
||||
<?endif;?>
|
||||
</style>
|
||||
|
||||
:share_edit_global1_help:
|
||||
<?if ($name):?>
|
||||
:share_edit_global2_help:
|
||||
<?endif;?>
|
||||
|
||||
<div class="clone1">
|
||||
<span class="clone">_(Read settings from)_</span><i class="fa fa-arrow-left fa-fw"></i>
|
||||
<span class="wrap"><select name="readshare" class="clone" onchange="toggleButton('readshare',false)">
|
||||
<option disabled selected>_(select)_...</option>
|
||||
<?
|
||||
foreach ($shares as $list) if ($list['name']!=$name || !$name) echo mk_option("", $list['name'], compress($list['name']));
|
||||
?>
|
||||
</select></span><input type="button" id="readshare" value="_(Read)_" class="clone" onclick="readShare()" disabled>
|
||||
</div>
|
||||
<?if ($name):?>
|
||||
<div class="clone2">
|
||||
<span class="clone">_(Write settings to)_</span><i class="fa fa-arrow-right fa-fw"></i>
|
||||
<span class="wrap"><select id="s5" name="writeshare" multiple onchange="toggleButton('writeshare',this.id)">
|
||||
<?
|
||||
$rows = [];
|
||||
foreach ($shares as $list) if ($list['name']!=$name) $rows[] = mk_option("", $list['name'], compress($list['name']));
|
||||
if ($rows) echo "<option>("._('All').")</option>";
|
||||
foreach ($rows as $row) echo $row;
|
||||
?>
|
||||
</select></span><input type="button" id="writeshare" value="_(Write)_" class="clone" onclick="writeShare()" disabled>
|
||||
</div>
|
||||
<?endif;?>
|
||||
|
||||
<form markdown="1" name="share_edit" method="POST" action="/update.htm" target="progressFrame" onsubmit="return prepareEdit()"<?=$name?" onchange=\"toggleButton('writeshare',true);$('#s5').dropdownchecklist('disable')\">":">"?>
|
||||
<input type="hidden" name="shareNameOrig" value="<?=htmlspecialchars($share['nameOrig'])?>">
|
||||
<input type="hidden" name="shareUseCache" value="<?=$share['useCache']?>">
|
||||
<input type="hidden" name="shareAllocator" value="">
|
||||
<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)_:
|
||||
: <input type="text" id="shareName" name="shareName" maxlength="40" autocomplete="off" spellcheck="false" value="<?=htmlspecialchars($name)?>" oninput="checkName(this.value)" title="_(Hidden share names are not allowed)_" pattern="^[^\.].*"><span id="zfs-name" class="orange-text"><i class="fa fa-warning"></i> _(Share name contains invalid characters for ZFS use)_</span>
|
||||
|
||||
:share_edit_name_help:
|
||||
|
||||
_(Comments)_:
|
||||
: <input type="text" name="shareComment" maxlength="256" autocomplete="off" spellcheck="false" value="<?=htmlspecialchars($share['comment'])?>">
|
||||
|
||||
: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>
|
||||
|
||||
:share_edit_free_space_help:
|
||||
|
||||
</div>
|
||||
<?endif;?>
|
||||
<?if ($name):?>
|
||||
<div markdown="1" class="empty">
|
||||
_(Share status)_:
|
||||
: _(Share is empty)_
|
||||
|
||||
:share_edit_status_help:
|
||||
|
||||
</div>
|
||||
<div markdown="1" class="full">
|
||||
_(Share status)_:
|
||||
: <span class="full1"> </span><span class="full2">_(Share contains data)_</span>
|
||||
|
||||
:share_edit_delete_help:
|
||||
|
||||
</div>
|
||||
<?if (_var($share,'exclusive')=="yes"):?>
|
||||
_(Exclusive access)_:
|
||||
: _(Yes)_
|
||||
|
||||
:share_edit_exclusive_access_help:
|
||||
|
||||
<?else:?>
|
||||
_(Exclusive access)_:
|
||||
: _(No)_
|
||||
|
||||
:share_edit_exclusive_access_help:
|
||||
|
||||
<?endif;?>
|
||||
<?endif;?>
|
||||
</div>
|
||||
<div markdown="1" class="shade-<?=$display['theme']?>">
|
||||
_(Primary storage (for new files and folders))_:
|
||||
: <select id="primary" name="shareCachePool" onchange="form.shareFloor.value='';updateScreen(z(4),'slow')">
|
||||
<?=mk_option(primary(),'',_('Array'))?>
|
||||
<?foreach ($pools as $pool):?>
|
||||
<?if ($disks[$pool]['devices']) echo mk_option(primary(),$pool,my_disk($pool),$disks[$pool]['shareEnabled']=='yes'?"":"disabled")?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
:share_edit_primary_storage_help:
|
||||
|
||||
<div markdown="1" id="cow-setting">
|
||||
_(Enable Copy-on-write)_:
|
||||
: <span class="input"><select name="shareCOW"<?if ($name):?> disabled<?endif;?>>
|
||||
<?=mk_option($share['cow'], "no", _('No'))?>
|
||||
<?=mk_option($share['cow'], "auto", _('Auto'))?>
|
||||
</select></span><?if ($name):?><i class='fa fa-info i'></i>_(Set when adding new share only)_<?endif;?>
|
||||
|
||||
:share_edit_copy_on_write_help:
|
||||
|
||||
</div>
|
||||
<div markdown="1" id="moreSettings1">
|
||||
_(Allocation method)_:
|
||||
: <select name="shareAllocator1">
|
||||
<?=mk_option($share['allocator'], "highwater", _('High-water'))?>
|
||||
<?=mk_option($share['allocator'], "fillup", _('Fill-up'))?>
|
||||
<?=mk_option($share['allocator'], "mostfree", _('Most-free'))?>
|
||||
</select>
|
||||
|
||||
:share_edit_allocation_method_help:
|
||||
|
||||
_(Split level)_:
|
||||
: <select name="shareSplitLevel1">
|
||||
<?=mk_option($share['splitLevel'], "", _('Automatically split any directory as required'))?>
|
||||
<?=mk_option($share['splitLevel'], "1", _('Automatically split only the top level directory as required'))?>
|
||||
<?=mk_option($share['splitLevel'], "2", _('Automatically split only the top two directory levels as required'))?>
|
||||
<?=mk_option($share['splitLevel'], "3", _('Automatically split only the top three directory levels as required'))?>
|
||||
<?=mk_option($share['splitLevel'], "4", _('Automatically split only the top four directory levels as required'))?>
|
||||
<?=mk_option($share['splitLevel'], "5", _('Automatically split only the top five directory levels as required'))?>
|
||||
<?=mk_option($share['splitLevel'], "0", _('Manual: do not automatically split directories'))?>
|
||||
</select>
|
||||
|
||||
:share_edit_split_level_help:
|
||||
|
||||
_(Included disk(s))_:
|
||||
: <select id="s1" name="shareInclude1" multiple>
|
||||
<?foreach ($myDisks as $disk):?>
|
||||
<?=mk_option_luks($disk, $share['include'], strstr(_var($disks[$disk],'fsType'),':',true))?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
:share_edit_included_disks_help:
|
||||
|
||||
_(Excluded disk(s))_:
|
||||
: <select id="s2" name="shareExclude1" multiple>
|
||||
<?foreach ($myDisks as $disk):?>
|
||||
<?=mk_option_luks($disk, $share['exclude'], strstr(_var($disks[$disk],'fsType'),':',true))?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
:share_edit_excluded_disks_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div markdown="1" class="shade-<?=$display['theme']?>">
|
||||
_(Secondary storage)_:
|
||||
: <select id="secondary" onchange="updateScreen(z(4),'slow')">
|
||||
<?=mk_option(secondary(),'0',_('None'))?>
|
||||
<?=mk_option(secondary(),'1',_('Array'))?>
|
||||
</select>
|
||||
|
||||
:share_edit_secondary_storage_help:
|
||||
|
||||
<div markdown="1" id="moreSettings2">
|
||||
_(Allocation method)_:
|
||||
: <select name="shareAllocator2">
|
||||
<?=mk_option($share['allocator'], "highwater", _('High-water'))?>
|
||||
<?=mk_option($share['allocator'], "fillup", _('Fill-up'))?>
|
||||
<?=mk_option($share['allocator'], "mostfree", _('Most-free'))?>
|
||||
</select>
|
||||
|
||||
:share_edit_allocation_method_help:
|
||||
|
||||
_(Split level)_:
|
||||
: <select name="shareSplitLevel2">
|
||||
<?=mk_option($share['splitLevel'], "", _('Automatically split any directory as required'))?>
|
||||
<?=mk_option($share['splitLevel'], "1", _('Automatically split only the top level directory as required'))?>
|
||||
<?=mk_option($share['splitLevel'], "2", _('Automatically split only the top two directory levels as required'))?>
|
||||
<?=mk_option($share['splitLevel'], "3", _('Automatically split only the top three directory levels as required'))?>
|
||||
<?=mk_option($share['splitLevel'], "4", _('Automatically split only the top four directory levels as required'))?>
|
||||
<?=mk_option($share['splitLevel'], "5", _('Automatically split only the top five directory levels as required'))?>
|
||||
<?=mk_option($share['splitLevel'], "0", _('Manual: do not automatically split directories'))?>
|
||||
</select>
|
||||
|
||||
:share_edit_split_level_help:
|
||||
|
||||
_(Included disk(s))_:
|
||||
: <select id="s3" name="shareInclude2" multiple>
|
||||
<?foreach ($myDisks as $disk):?>
|
||||
<?=mk_option_luks($disk, $share['include'], strstr(_var($disks[$disk],'fsType'),':',true))?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
:share_edit_included_disks_help:
|
||||
|
||||
_(Excluded disk(s))_:
|
||||
: <select id="s4" name="shareExclude2" multiple>
|
||||
<?foreach ($myDisks as $disk):?>
|
||||
<?=mk_option_luks($disk, $share['exclude'], strstr(_var($disks[$disk],'fsType'),':',true))?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
:share_edit_excluded_disks_help:
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div markdown="1" class="shade-<?=$display['theme']?>">
|
||||
<div markdown="1" id="moverDirection1">
|
||||
_(Mover action)_:
|
||||
: <span class="input"><select id="direction" onchange="updateScreen(z(3),'slow')">
|
||||
<?=mk_option(direction(),'0','')?>
|
||||
<?=mk_option(direction(),'1','')?>
|
||||
</select></span><span id="moverAction1"></span>
|
||||
|
||||
:share_edit_mover_action_help:
|
||||
|
||||
</div>
|
||||
<div markdown="1" id="moverDirection2">
|
||||
_(Mover action)_:
|
||||
: <span class="input"><select disabled>
|
||||
<?=mk_option('','',"_(Not used)_")?>
|
||||
</select></span><span id="moverAction2"></span>
|
||||
|
||||
:share_edit_mover_action_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?if (!$name):?>
|
||||
|
||||
: <input type="submit" name="cmdEditShare" value="_(Add Share)_" onclick="this.value='Add Share'"><input type="button" value="_(Done)_" onclick="done()">
|
||||
<?else:?>
|
||||
<div markdown="1" class="empty">
|
||||
_(Delete)_<input type="checkbox" name="confirmDelete" onchange="chkDelete(this.form, document.getElementById('cmdEditShare'));">
|
||||
: <input type="submit" id="cmdEditShare" name="cmdEditShare" value="_(Apply)_" onclick="if (this.value=='_(Delete)_') this.value='Delete'; else this.value='Apply'" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</div>
|
||||
<div markdown="1" class="full">
|
||||
|
||||
: <input type="submit" name="cmdEditShare" value="_(Apply)_" onclick="this.value='Apply'" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</div>
|
||||
<?endif;?>
|
||||
</form>
|
||||
<script>
|
||||
var form = document.share_edit;
|
||||
|
||||
$(function() {
|
||||
<?if ($name):?>
|
||||
$.post('/webGui/include/ShareList.php',{scan:"<?=$name?>"},function(e){
|
||||
if (e==1) {$('.empty').show(); $('.full').hide();} else {$('.full1').hide(); $('.full2').show();}
|
||||
});
|
||||
<?endif;?>
|
||||
initDropdown(false,true);
|
||||
<?if ($tabbed):?>
|
||||
$('#tab1').bind({click:function(){initDropdown(true,true);}});
|
||||
<?endif;?>
|
||||
updateScreen(form.shareUseCache.value);
|
||||
if ($.cookie('autosize-'+$('#shareName').val())) $('#autosize').show();
|
||||
checkName($('#shareName').val());
|
||||
});
|
||||
function initDropdown(remove,create) {
|
||||
if (remove) {
|
||||
$('#s1').dropdownchecklist('destroy');
|
||||
$('#s2').dropdownchecklist('destroy');
|
||||
$('#s3').dropdownchecklist('destroy');
|
||||
$('#s4').dropdownchecklist('destroy');
|
||||
<?if ($name):?>
|
||||
$('#s5').dropdownchecklist('destroy');
|
||||
<?endif;?>
|
||||
}
|
||||
if (create) {
|
||||
$('#s1').dropdownchecklist({emptyText:"_(All)_", width:<?=$width[1]?>, explicitClose:"..._(close)_"});
|
||||
$('#s2').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[1]?>, explicitClose:"..._(close)_"});
|
||||
$('#s3').dropdownchecklist({emptyText:"_(All)_", width:<?=$width[1]?>, explicitClose:"..._(close)_"});
|
||||
$('#s4').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[1]?>, explicitClose:"..._(close)_"});
|
||||
<?if ($name):?>
|
||||
$("#s5").dropdownchecklist({firstItemChecksAll:true, emptyText:"_(select)_...", width:<?=$width[0]?>, explicitClose:"..._(close)_"});
|
||||
<?endif;?>
|
||||
}
|
||||
}
|
||||
function z(i) {
|
||||
switch (i) {
|
||||
case 0: return $('#primary').prop('selectedIndex');
|
||||
case 1: return $('#secondary').prop('selectedIndex');
|
||||
case 2: return $('#direction').prop('selectedIndex');
|
||||
case 3: return z(2)==0 ? 'yes' : 'prefer';
|
||||
case 4: return z(0)==0 ? 'no' : (z(1)==0 ? 'only' : z(3));
|
||||
}
|
||||
}
|
||||
function updateCOW(i,slow) {
|
||||
const fsType = {<?=fsType()?>};
|
||||
if (fsType[i]=='btrfs') $('#cow-setting').show(slow); else $('#cow-setting').hide(slow);
|
||||
}
|
||||
function updateScreen(cache,slow) {
|
||||
switch (cache) {
|
||||
case 'no':
|
||||
$('#primary option:eq('+z(0)+')').prop('selected',true);
|
||||
$('#secondary option:eq(0)').prop('selected',true);
|
||||
$('#secondary option:eq(1)').prop('disabled',true);
|
||||
$('#moverDirection1').hide();
|
||||
$('#moverDirection2').show();
|
||||
$('#moreSettings1').show(slow);
|
||||
$('#moreSettings2').hide(slow);
|
||||
$('#cow-setting').hide(slow);
|
||||
form.shareAllocator.disabled = false;
|
||||
form.shareSplitLevel.disabled = false;
|
||||
$('#s1').dropdownchecklist('enable');
|
||||
$('#s2').dropdownchecklist('enable');
|
||||
$('#moverAction2').html("<i class='fa fa-info i'></i>_(Mover takes no action)_");
|
||||
break;
|
||||
case 'yes':
|
||||
$('#primary option:eq('+z(0)+')').prop('selected',true);
|
||||
$('#secondary option:eq('+z(1)+')').prop('selected',true);
|
||||
$('#secondary option:eq(1)').prop('disabled',false);
|
||||
$('#moverDirection1 option:eq(0)').text($('#primary option:eq('+z(0)+')').text()+' → '+$('#secondary option:eq('+z(1)+')').text());
|
||||
$('#moverDirection1 option:eq(1)').text($('#secondary option:eq('+z(1)+')').text()+' → '+$('#primary option:eq('+z(0)+')').text());
|
||||
$('#moverDirection1').val('0').show();
|
||||
$('#moverDirection2').hide();
|
||||
$('#moreSettings1').hide(slow);
|
||||
$('#moreSettings2').show(slow);
|
||||
updateCOW(form.shareCachePool.value,slow);
|
||||
form.shareAllocator.disabled = false;
|
||||
form.shareSplitLevel.disabled = false;
|
||||
$('#s3').dropdownchecklist('enable');
|
||||
$('#s4').dropdownchecklist('enable');
|
||||
$('#moverAction1').html("<i class='fa fa-info i'></i>_(Mover transfers files from Primary storage to Secondary storage)_");
|
||||
break;
|
||||
case 'only':
|
||||
$('#primary option:eq('+z(0)+')').prop('selected',true);
|
||||
$('#secondary option:eq('+z(1)+')').prop('selected',true);
|
||||
$('#secondary option:eq(1)').prop('disabled',false);
|
||||
$('#moverDirection1').hide();
|
||||
$('#moverDirection2').show();
|
||||
$('#moreSettings1').hide(slow);
|
||||
$('#moreSettings2').hide(slow);
|
||||
updateCOW(form.shareCachePool.value,slow);
|
||||
form.shareAllocator.disabled = true;
|
||||
form.shareSplitLevel.disabled = true;
|
||||
$('#s1').dropdownchecklist('disable');
|
||||
$('#s2').dropdownchecklist('disable');
|
||||
$('#moverAction2').html("<i class='fa fa-info i'></i>_(Mover takes no action)_");
|
||||
break;
|
||||
case 'prefer':
|
||||
$('#primary option:eq('+z(0)+')').prop('selected',true);
|
||||
$('#secondary option:eq('+z(1)+')').prop('selected',true);
|
||||
$('#secondary option:eq(1)').prop('disabled',false);
|
||||
$('#moverDirection1 option:eq(0)').text($('#primary option:eq('+z(0)+')').text()+' → '+$('#secondary option:eq('+z(1)+')').text());
|
||||
$('#moverDirection1 option:eq(1)').text($('#secondary option:eq('+z(1)+')').text()+' → '+$('#primary option:eq('+z(0)+')').text());
|
||||
$('#moverDirection1').val('1').show();
|
||||
$('#moverDirection2').hide();
|
||||
$('#moreSettings1').hide(slow);
|
||||
$('#moreSettings2').show(slow);
|
||||
updateCOW(form.shareCachePool.value,slow);
|
||||
form.shareAllocator.disabled = false;
|
||||
form.shareSplitLevel.disabled = false;
|
||||
$('#s3').dropdownchecklist('enable');
|
||||
$('#s4').dropdownchecklist('enable');
|
||||
$('#moverAction1').html("<i class='fa fa-info i'></i>_(Mover transfers files from Secondary storage to Primary storage)_");
|
||||
break;
|
||||
}
|
||||
}
|
||||
function unite(field) {
|
||||
var list = [];
|
||||
for (var i=0,item; item=field.options[i]; i++) if (item.selected) list.push(item.value);
|
||||
return list.join(',');
|
||||
}
|
||||
function setFloor(val) {
|
||||
const fsSize = {<?=fsSize()?>};
|
||||
const units = ['K','M','G','T','P','E','Z','Y'];
|
||||
var full = fsSize[$('#primary').val()];
|
||||
var size = parseInt(full * 0.1); // 10% of available size
|
||||
var number = val.replace(/[A-Z%\s]/gi,'').replace(',','.').split('.');
|
||||
var last = number.pop();
|
||||
number = number.length ? number.join('')+'.'+last : last;
|
||||
if (number==0 && size>0) {
|
||||
size = size.toString()
|
||||
$.cookie('autosize-'+$('#shareName').val(),'1',{expires:365});
|
||||
} else {
|
||||
size = val;
|
||||
$.removeCookie('autosize-'+$('#shareName').val());
|
||||
}
|
||||
var unit = size.replace(/[0-9.,\s]/g,'');
|
||||
if (unit=='%') {
|
||||
number = (number > 0 && number <= 100) ? parseInt(full * number / 100) : '';
|
||||
} else {
|
||||
var base = unit.length==2 ? 1000 : (unit.length==1 ? 1024 : 0);
|
||||
number = base>0 ? number * Math.pow(base,(units.indexOf(unit.toUpperCase().replace('B',''))||0)) : size;
|
||||
}
|
||||
return isNaN(number) ? '' : number;
|
||||
}
|
||||
// Compose input fields
|
||||
function prepareEdit() {
|
||||
// Test share name validity
|
||||
var share = form.shareName.value.trim();
|
||||
if (share.length==0) {
|
||||
swal({title:"_(Missing share name)_",text:"_(Enter a name for the share)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
var reserved = [<?=implode(',',array_map('escapestring',explode(',',$var['reservedNames'])))?>];
|
||||
if (reserved.includes(share)) {
|
||||
swal({title:"_(Invalid share name)_",text:"_(Do not use reserved names)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
var pools = [<?=implode(',',array_map('escapestring',$pools))?>];
|
||||
if (pools.includes(share)) {
|
||||
swal({title:"_(Invalid share name)_",text:"_(Do not use pool names)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
if (share.match('[:\\\/*<>|"?]')) {
|
||||
swal({title:"_(Invalid Characters)_",text:"_(You cannot use the following within share names)_"+'<b> \\ / : * < > | " ?</b>',type:'error',html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
// Update settings
|
||||
form.shareName.value = share;
|
||||
form.shareUseCache.value = z(4);
|
||||
form.shareFloor.value = setFloor(form.shareFloor.value);
|
||||
switch (form.shareUseCache.value) {
|
||||
case 'no':
|
||||
form.shareAllocator.value = form.shareAllocator1.value;
|
||||
form.shareSplitLevel.value = form.shareSplitLevel1.value;
|
||||
form.shareInclude.value = unite(form.shareInclude1);
|
||||
form.shareExclude.value = unite(form.shareExclude1);
|
||||
break;
|
||||
case 'yes':
|
||||
case 'prefer':
|
||||
form.shareAllocator.value = form.shareAllocator2.value;
|
||||
form.shareSplitLevel.value = form.shareSplitLevel2.value;
|
||||
form.shareInclude.value = unite(form.shareInclude2);
|
||||
form.shareExclude.value = unite(form.shareExclude2);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function readShare() {
|
||||
var name = $('select[name="readshare"]').val();
|
||||
initDropdown(true,false);
|
||||
$.get('/webGui/include/ShareData.php',{name:name},function(json) {
|
||||
var data = $.parseJSON(json);
|
||||
form.shareAllocator.value = data.allocator;
|
||||
form.shareFloor.value = data.floor;
|
||||
form.shareSplitLevel.value = data.splitLevel;
|
||||
form.shareInclude.value = data.include;
|
||||
form.shareExclude.value = data.exclude;
|
||||
form.shareUseCache.value = data.useCache;
|
||||
form.shareCOW.value = data.cow;
|
||||
for (var i=0,disk; disk=data.include.split(',')[i]; i++) for (var j=0,include; include=form.shareInclude.options[j]; j++) if (include.value==disk) include.selected=true;
|
||||
for (var i=0,disk; disk=data.exclude.split(',')[i]; i++) for (var j=0,exclude; exclude=form.shareExclude.options[j]; j++) if (exclude.value==disk) exclude.selected=true;
|
||||
initDropdown(false,true);
|
||||
});
|
||||
$(form).find('select').trigger('change');
|
||||
}
|
||||
function writeShare(data,n,i) {
|
||||
if (data) {
|
||||
if (n<i) {
|
||||
$.post('/update.htm',data[n], function(){setTimeout(function(){writeShare(data,++n,i);},3000);});
|
||||
} else {
|
||||
toggleButton('writeshare',false);
|
||||
$('div.spinner.fixed').hide();
|
||||
}
|
||||
} else {
|
||||
var data = [], i = 0;
|
||||
$('select#s5 option').map(function() {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(All)') {
|
||||
data[i] = {};
|
||||
data[i]['shareName'] = $(this).val();
|
||||
data[i]['shareNameOrig'] = $(this).val();
|
||||
data[i]['shareAllocator'] = '<?=addslashes(htmlspecialchars($share['allocator']))?>';
|
||||
data[i]['shareFloor'] = '<?=addslashes(htmlspecialchars($share['floor']))?>';
|
||||
data[i]['shareSplitLevel'] = '<?=addslashes(htmlspecialchars($share['splitLevel']))?>';
|
||||
data[i]['shareInclude'] = '<?=addslashes(htmlspecialchars($share['include']))?>';
|
||||
data[i]['shareExclude'] = '<?=addslashes(htmlspecialchars($share['exclude']))?>';
|
||||
data[i]['shareUseCache'] = '<?=addslashes(htmlspecialchars($share['useCache']))?>';
|
||||
data[i]['cmdEditShare'] = 'Apply';
|
||||
i++;
|
||||
}
|
||||
});
|
||||
toggleButton('writeshare',true);
|
||||
$('div.spinner.fixed').show('slow');
|
||||
writeShare(data,0,i);
|
||||
}
|
||||
}
|
||||
function checkName(name) {
|
||||
if (/^[A-Za-z0-9-_.: ]*$/.test(name)) $('#zfs-name').hide(); else $('#zfs-name').show();
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,66 @@
|
||||
Menu="Shares:1"
|
||||
Title="User Shares"
|
||||
Tag="user-circle"
|
||||
Cond="_var($var,'fsState')!='Stopped' && _var($var,'shareUser')=='e'"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<style>
|
||||
table.share_status thead tr td:first-child{width:15%}
|
||||
table.share_status thead tr td:nth-child(n+3){width:9%!important}
|
||||
table.share_status thead tr td:nth-child(5){width:13%!important}
|
||||
td.empty{text-align:center;padding-top:12px}
|
||||
i.fa-fw{margin-right:2px}
|
||||
</style>
|
||||
|
||||
<table class="share_status">
|
||||
<thead><tr><td>_(Name)_</td><td>_(Comment)_</td><td>_(SMB)_</td><td>_(NFS)_</td><td>_(Storage)_</td><td>_(Size)_</td><td>_(Free)_</td></tr></thead>
|
||||
<tbody id="shareslist"></tbody>
|
||||
</table>
|
||||
|
||||
<form name="share_form" method="POST" action="<?=htmlspecialchars($path)?>/Share?name=">
|
||||
<input type="button" id="compute-shares" value="_(Compute All)_" onclick="$(this).prop('disabled',true);shareList('',-1)">
|
||||
<input type="submit" value="_(Add Share)_">
|
||||
<input type="button" value="_(Clean Up)_" onclick="cleanup()" id="cleanup-button" disabled>
|
||||
</form>
|
||||
|
||||
:share_list_help:
|
||||
|
||||
<script>
|
||||
function shareList(name,all) {
|
||||
timers.shareList = setTimeout(function(){$('div.spinner.fixed').show();},500);
|
||||
$.post('/webGui/include/ShareList.php',{compute:name,path:"<?=rawurlencode($path)?>",all:all},function(data){
|
||||
clearTimeout(timers.shareList);
|
||||
$('div.spinner.fixed').hide();
|
||||
$('#shareslist').html(data);
|
||||
if (all!=1) $('#compute-shares').prop('disabled',!data||data.indexOf('colspan=')!=-1);
|
||||
});
|
||||
}
|
||||
function computeShare(name,status) {
|
||||
status.html("<i class='fa fa-circle-o-notch fa-spin'></i> _(Please wait)_...");
|
||||
shareList(name,1);
|
||||
}
|
||||
function cleanup() {
|
||||
swal({title:"_(CLEAN UP)_",text:"_(Remove unused share configurations)_",type:'info',html:true,animation:'none',showCancelButton:true,closeOnConfirm:false,confirmButtonText:"<?=_('Proceed')?>",cancelButtonText:"<?=_('Cancel')?>"},function(cleanup){
|
||||
if (!cleanup) return;
|
||||
$.post('/webGui/include/ShareList.php',{cleanup:1},function(data){
|
||||
swal({title:"_(CLEAN UP)_",text:"_(Removed share configurations)_: "+data,type:"success",html:true,confirmButtonText:"_(Ok)_"},function(esc){$('#cleanup-button').prop('disabled',true);});
|
||||
});
|
||||
});
|
||||
}
|
||||
$(function(){
|
||||
// enable CLEAN_UP button only when unused files are present
|
||||
$.post('/webGui/include/ShareList.php',{cleanup:0},function(data){if (data>0) $('#cleanup-button').prop('disabled',false);});
|
||||
shareList('',0);
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,128 @@
|
||||
Menu="OtherSettings"
|
||||
Type="xmenu"
|
||||
Title="Global Share Settings"
|
||||
Icon="icon-share"
|
||||
Tag="share-alt"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$disabled = _var($var,'fsState')!='Stopped' ? 'disabled' : '';
|
||||
$disks = array_filter($disks,'my_disks');
|
||||
$width = [166,300];
|
||||
?>
|
||||
<script>
|
||||
$(function() {
|
||||
$('#s1').dropdownchecklist({emptyText:"_(All)_", width:<?=$width[0]?>, explicitClose:"..._(close)_"});
|
||||
$('#s2').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[0]?>, explicitClose:"..._(close)_"});
|
||||
presetShare(document.share_settings);
|
||||
});
|
||||
// Simulate the original input field
|
||||
function prepareShare(form) {
|
||||
var include = '';
|
||||
for (var i=0,item; item=form.shareUserInclude.options[i]; i++) {
|
||||
if (item.selected) {
|
||||
if (include.length) include += ',';
|
||||
include += item.value;
|
||||
item.selected = false;
|
||||
}
|
||||
}
|
||||
item = form.shareUserInclude.options[0];
|
||||
item.value = include;
|
||||
item.selected = true;
|
||||
var exclude = '';
|
||||
for (var i=0,item; item=form.shareUserExclude.options[i]; i++) {
|
||||
if (item.selected) {
|
||||
if (exclude.length) exclude += ',';
|
||||
exclude += item.value;
|
||||
item.selected = false;
|
||||
}
|
||||
}
|
||||
item = form.shareUserExclude.options[0];
|
||||
item.value = exclude;
|
||||
item.selected = true;
|
||||
}
|
||||
function presetShare(form,shares) {
|
||||
var disabled = shares==null ? <?=$disabled ? 'true':'false'?> : shares=='-';
|
||||
var onOff = disabled ? 'disable':'enable';
|
||||
form.shareUserInclude.disabled = disabled;
|
||||
form.shareUserExclude.disabled = disabled;
|
||||
$('#s1').dropdownchecklist(onOff);
|
||||
$('#s2').dropdownchecklist(onOff);
|
||||
}
|
||||
</script>
|
||||
<form markdown="1" name="share_settings" method="POST" action="/update.htm" target="progressFrame" onsubmit="prepareShare(this)">
|
||||
|
||||
_(Enable disk shares)_:
|
||||
: <select name="shareDisk" <?=$disabled?>>
|
||||
<?=mk_option($var['shareDisk'], "no", _('No'))?>
|
||||
<?=mk_option($var['shareDisk'], "yes", _('Yes'))?>
|
||||
<?=mk_option($var['shareDisk'], "auto", _('Auto'))?>
|
||||
</select>
|
||||
|
||||
:shares_enable_disk_help:
|
||||
|
||||
_(Enable user shares)_:
|
||||
: <select name="shareUser" onchange="presetShare(this.form,this.value)" <?=$disabled?>>
|
||||
<?=mk_option($var['shareUser'], "e", _('Yes'))?>
|
||||
<?=mk_option($var['shareUser'], "-", _('No'))?>
|
||||
</select>
|
||||
|
||||
:shares_enable_shares_help:
|
||||
|
||||
_(Included disk(s))_:
|
||||
: <select id="s1" name="shareUserInclude" multiple="multiple" style="display:none">
|
||||
<?foreach ($disks as $disk):?>
|
||||
<?=mk_option_luks(_var($disk,'name'),_var($var,'shareUserInclude'),strstr(_var($disk,'fsType'),':',true))?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
:shares_included_disks_help:
|
||||
|
||||
_(Excluded disk(s))_:
|
||||
: <select id="s2" name="shareUserExclude" multiple="multiple" style="display:none">
|
||||
<?foreach ($disks as $disk):?>
|
||||
<?=mk_option_luks(_var($disk,'name'),_var($var,'shareUserExclude'),strstr(_var($disk,'fsType'),':',true))?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
:shares_excluded_disks_help:
|
||||
|
||||
_(Permit exclusive shares)_:
|
||||
: <select name="shareUserExclusive" <?=$disabled?>>
|
||||
<?=mk_option($var['shareUserExclusive'], "no", _('No'))?>
|
||||
<?=mk_option($var['shareUserExclusive'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:shares_exclusive_shares_help:
|
||||
|
||||
_(Tunable (support Hard Links))_:
|
||||
: <select name="fuse_useino" <?=$disabled?>>
|
||||
<?=mk_option($var['fuse_useino'], "no", _('No'))?>
|
||||
<?=mk_option($var['fuse_useino'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:shares_tunable_hard_links_help:
|
||||
|
||||
_(Tunable (enable Direct IO))_:
|
||||
: <select name="fuse_directio" <?=$disabled?>>
|
||||
<?=mk_option($var['fuse_directio'], "auto", _('Auto'))?>
|
||||
<?=mk_option($var['fuse_directio'], "0", _('No'))?>
|
||||
<?=mk_option($var['fuse_directio'], "1", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:shares_tunable_direct_io_help:
|
||||
|
||||
|
||||
: <input type="submit" name="changeShare" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()"><?if ($disabled):?>*_(Array must be **Stopped** to change)_*<?endif;?>
|
||||
</form>
|
||||
@@ -0,0 +1,11 @@
|
||||
Menu="Tasks:2"
|
||||
Type="xmenu"
|
||||
Code="e92a"
|
||||
---
|
||||
<?PHP
|
||||
if ($var['fsState']=="Stopped") {
|
||||
echo "<p class='notice shift'>"._('Array must be **Started** to view Shares').".</p>";
|
||||
return;
|
||||
}
|
||||
if (count($pages)==2) $tabbed = false;
|
||||
?>
|
||||
@@ -0,0 +1,190 @@
|
||||
Menu="Notifications:2"
|
||||
Title="SMTP Settings"
|
||||
Tag="envelope"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
require_once "$docroot/webGui/include/Encryption.php";
|
||||
|
||||
$ssmtp['AuthPass'] = base64_decrypt(_var($ssmtp,'AuthPass'));
|
||||
$incomplete = !_var($ssmtp,'root') || !_var($ssmtp,'server') || !_var($ssmtp,'port') || ((!_var($ssmtp,'AuthUser') || !_var($ssmtp,'AuthPass')) && _var($ssmtp,'AuthMethod')!='none');
|
||||
?>
|
||||
<script>
|
||||
var counter,pid;
|
||||
|
||||
$(function() {
|
||||
$('#testbutton').click(function(){
|
||||
$('#testresult').html('_(Test running)_:<span class="orange">_(obtaining)_ <span id="testcounter"></span>...</span>');
|
||||
counter = 20;
|
||||
mailtest();
|
||||
$.get('/webGui/include/SMTPtest.php',function(data){clearTimeout(pid); $('#testresult').html(data)});
|
||||
});
|
||||
tls(document.smtp_setup);
|
||||
pwd(document.smtp_setup);
|
||||
});
|
||||
function mailcheck(form) {
|
||||
var email = /^\S+@\S+\.\S+/;
|
||||
if (!email.test(form.root.value)) {
|
||||
swal({title:"_(Invalid email address)_",text:"_(Please enter a valid sending email address)_",type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function tls(form) {
|
||||
form.TLSCert.disabled = form.UseTLSCert.selectedIndex==0;
|
||||
}
|
||||
function pwd(form) {
|
||||
form.AuthUser.disabled = form.AuthMethod.selectedIndex==0;
|
||||
form.AuthPass.disabled = form.AuthMethod.selectedIndex==0;
|
||||
}
|
||||
function mailtest() {
|
||||
document.getElementById('testcounter').innerHTML = '('+counter+' sec)';
|
||||
counter--;
|
||||
if (counter>0) pid=setTimeout(mailtest,1000);
|
||||
}
|
||||
function disableTest() {
|
||||
document.getElementById('testbutton').disabled = true;
|
||||
}
|
||||
function settings(form, data) {
|
||||
var item = data.split(':');
|
||||
form.server.value = item[0];
|
||||
form.port.value = item[1];
|
||||
form.UseTLS.value = item[2];
|
||||
form.UseSTARTTLS.value = item[3];
|
||||
form.AuthMethod.value = item[4];
|
||||
disableTest();
|
||||
}
|
||||
</script>
|
||||
|
||||
<form markdown="1" name="smtp_setup" method="POST" action="/update.php" target="progressFrame" onsubmit="return mailcheck(this)" onchange="disableTest()">
|
||||
<input type="hidden" name="#file" value="dynamix/dynamix.cfg">
|
||||
<input type="hidden" name="#section" value="ssmtp">
|
||||
<input type="hidden" name="#include" value="/webGui/include/update.ssmtp.php">
|
||||
<input type="hidden" name="#command" value="/webGui/scripts/notify">
|
||||
<input type="hidden" name="#arg[1]" value="smtp-init">
|
||||
_(Preset service)_:
|
||||
: <select name="service" size="1" onchange="settings(this.form,this.value)">
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.gmail.com:465:YES:NO:login", "Gmail")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.gmail.com:587:YES:YES:login", "Gmail with TLS")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.office365.com:587:YES:YES:login", "Outlook")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.office365.com:587:YES:YES:login", "Hotmail")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.office365.com:587:YES:YES:login", "Office365")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.mail.yahoo.com:465:YES:NO:login", "Yahoo")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "plus.smtp.mail.yahoo.com:465:YES:NO:login", "Yahoo Plus")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.mail.yahoo.co.uk:465:YES:NO:login", "Yahoo UK")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.mail.yahoo.com.au:465:YES:NO:login", "Yahoo AU/NZ")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.o2.ie:25:NO:NO:login", "O2")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.o2.co.uk:25:NO:NO:login", "O2 UK")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.o2online.de:25:NO:NO:login", "O2 Online Deutschland")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "securesmtp.t-online.de:587:YES:YES:login", "T-Online Deutschland")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.1and1.com:587:YES:YES:login", "1&1")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.1und1.de:587:YES:YES:login", "1&1 Deutschland")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.att.yahoo.com:465:YES:NO:login", "AT&T")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.ntlworld.com:465:YES:NO:login", "NTL")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "mail.btopenworld.com:25:NO:NO:login", "BT Openworld")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "mail.btinternet.com:25:NO:NO:login", "BT Internet")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.comcast.net:465:YES:NO:login", "Comcast")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "outgoing.verizon.net:465:YES:NO:login", "Verizon")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "outgoing.yahoo.verizon.net:587:NO:NO:login", "Verizon (Yahoo hosted)")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.mail.com:465:YES:NO:login", "Mail.com")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.gmx.com:465:YES:NO:login", "GMX.com")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "smtp.zoho.com:465:YES:NO:login", "zoho Mail")?>
|
||||
<?=mk_option(_var($ssmtp,'service'), "::NO:NO:none", _("Custom"))?>
|
||||
</select>
|
||||
|
||||
:smtp_preset_service_help:
|
||||
|
||||
_(Sending email address)_:
|
||||
: <input type="text" name="root" value="<?=htmlspecialchars(_var($ssmtp,'root'))?>">
|
||||
|
||||
:smtp_email_address_help:
|
||||
|
||||
_(Email recipients)_:
|
||||
: <input type="text" name="RcptTo" value="<?=htmlspecialchars(_var($ssmtp,'RcptTo'))?>">
|
||||
|
||||
:smtp_recipients_help:
|
||||
|
||||
_(Priority in header)_:
|
||||
: <select name="SetEmailPriority">
|
||||
<?=mk_option(_var($ssmtp,'SetEmailPriority'), "False", _("No"))?>
|
||||
<?=mk_option(_var($ssmtp,'SetEmailPriority'), "True", _("Yes"))?>
|
||||
</select>
|
||||
|
||||
:smtp_priority_help:
|
||||
|
||||
_(Email subject prefix)_:
|
||||
: <input type="text" name="Subject" value="<?=htmlspecialchars(_var($ssmtp,'Subject'))?>">
|
||||
|
||||
:smtp_subject_prefix_help:
|
||||
|
||||
_(Mail server)_:
|
||||
: <input type="text" name="server" value="<?=htmlspecialchars(_var($ssmtp,'server'))?>">
|
||||
|
||||
:smtp_mail_server_help:
|
||||
|
||||
_(Mail server port)_:
|
||||
: <input type="text" name="port" class="narrow" maxlength="5" value="<?=htmlspecialchars(_var($ssmtp,'port'))?>">
|
||||
|
||||
:smtp_mail_server_port_help:
|
||||
|
||||
_(Use SSL/TLS)_:
|
||||
: <select name="UseTLS">
|
||||
<?=mk_option(_var($ssmtp,'UseTLS'), "NO", _("No"))?>
|
||||
<?=mk_option(_var($ssmtp,'UseTLS'), "YES", _("Yes"))?>
|
||||
</select>
|
||||
|
||||
:smtp_use_ssl_tls_help:
|
||||
|
||||
_(Use STARTTLS)_:
|
||||
: <select name="UseSTARTTLS">
|
||||
<?=mk_option(_var($ssmtp,'UseSTARTTLS'), "NO", _("No"))?>
|
||||
<?=mk_option(_var($ssmtp,'UseSTARTTLS'), "YES", _("Yes"))?>
|
||||
</select>
|
||||
|
||||
:smtp_use_starttls_help:
|
||||
|
||||
_(Define a TLS certificate)_:
|
||||
: <select name="UseTLSCert" onchange="tls(this.form)">
|
||||
<?=mk_option(_var($ssmtp,'UseTLSCert'), "NO", _("No"))?>
|
||||
<?=mk_option(_var($ssmtp,'UseTLSCert'), "YES", _("Yes"))?>
|
||||
</select>
|
||||
|
||||
:smtp_define_tls_cert_help:
|
||||
|
||||
_(TLS certificate location)_:
|
||||
: <input type="text" name="TLSCert" value="<?=htmlspecialchars(_var($ssmtp,'TLSCert'))?>">
|
||||
|
||||
:smtp_tls_cert_location_help:
|
||||
|
||||
_(Authentication method)_:
|
||||
: <select name="AuthMethod" onchange="pwd(this.form)">
|
||||
<?=mk_option(_var($ssmtp,'AuthMethod'), "none", _("None"))?>
|
||||
<?=mk_option(_var($ssmtp,'AuthMethod'), "cram-md5", _("CRAM-MD5"))?>
|
||||
<?=mk_option(_var($ssmtp,'AuthMethod'), "login", _("Login"))?>
|
||||
</select>
|
||||
|
||||
:smtp_authentication_method_help:
|
||||
|
||||
_(Username)_:
|
||||
: <input type="text" name="AuthUser" value="<?=htmlspecialchars(_var($ssmtp,'AuthUser'))?>">
|
||||
|
||||
_(Password)_:
|
||||
: <input type="password" name="AuthPass" value="<?=htmlspecialchars(_var($ssmtp,'AuthPass'))?>">
|
||||
|
||||
:smtp_username_password_help:
|
||||
|
||||
|
||||
: <input type="submit" name="#apply" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
<span id="testresult"><input type="button" id="testbutton" value="_(Test)_"<?if ($incomplete):?> disabled<?endif;?>></span>
|
||||
</form>
|
||||
@@ -0,0 +1,90 @@
|
||||
Menu="UNRAID-OS"
|
||||
Title="System Devices"
|
||||
Icon="icon-hardware"
|
||||
Tag="server"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
* Copyright 2012-2021, 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.
|
||||
*/
|
||||
?>
|
||||
<style>
|
||||
table.pre{margin-top:0;background:transparent}
|
||||
table.pre td:first-child{width:144px}
|
||||
table tr td{padding:0 0 3px 0;margin:0}
|
||||
table tr td.thin{line-height:8px;height:8px}
|
||||
</style>
|
||||
<script>
|
||||
$(function(){
|
||||
$('#t1').load('/webGui/include/SysDevs.php',{table:'t1'});
|
||||
$('#t2').load('/webGui/include/SysDevs.php',{table:'t2'});
|
||||
$('#t3').load('/webGui/include/SysDevs.php',{table:'t3'});
|
||||
$('#t4').load('/webGui/include/SysDevs.php',{table:'t4'});
|
||||
});
|
||||
function applyCfg() {
|
||||
var message = "_(System Devices)_: _(A reboot is required to apply changes)_";
|
||||
var string = "BIND=";
|
||||
var elements = document.getElementById("vfiopci").elements;
|
||||
for (var i = 0, element; element = elements[i++];) {
|
||||
if (element.type === "checkbox" && element.checked === true)
|
||||
string = string + element.value + " ";
|
||||
}
|
||||
string = string.trim();
|
||||
if (string === "BIND=") {
|
||||
string = "";
|
||||
}
|
||||
$.get( "/plugins/dynamix/include/update.vfio-pci-cfg.php", { cfg: string } )
|
||||
.done(function(d) {
|
||||
if (d==1) {
|
||||
addRebootNotice(message);
|
||||
document.getElementById("warning").innerHTML = "<b>_(ALERT)_: _(Changes saved)_. _(Reboot to take effect)_.</b>";
|
||||
} else {
|
||||
removeRebootNotice(message);
|
||||
document.getElementById("warning").innerHTML = "<b>_(No changes)_.</b>";
|
||||
}
|
||||
$("#applycfg").attr("disabled",true);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<?exec('ls /sys/kernel/iommu_groups/',$groups); ?>
|
||||
<?if (count($groups) > 0):?>
|
||||
**_(PCI Devices and IOMMU Groups)_**
|
||||
<?else:?>
|
||||
**_(PCI Devices (No IOMMU Groups Available))_**
|
||||
<?endif;?>
|
||||
|
||||
:sysdevs_iommu_groups_help:
|
||||
|
||||
<?if (strpos(file_get_contents('/proc/cmdline'), 'pcie_acs_override=') !== false):?>
|
||||
<p class="notice" style="line-height:30px;height:auto">_(Warning)_: _(Your system has booted with the PCIe ACS Override setting enabled)_. _(The below list doesn't not reflect the way IOMMU would naturally group devices)_.<br>
|
||||
<?=my_hyperlink(_("To see natural IOMMU groups for your hardware, go to the [VM Manager] page and set the **PCIe ACS override** setting to **Disabled**"),'/Settings/VMSettings')?>.</p>
|
||||
<?endif;?>
|
||||
|
||||
<pre><form id="vfiopci" class="js-confirm-leave" onsubmit="return false"><table id='t1' class='pre'><tr><td><div class="spinner"></div></td></tr></table></form></pre><br>
|
||||
|
||||
**_(CPU Thread Pairings)_**
|
||||
|
||||
:sysdevs_thread_pairings_help:
|
||||
|
||||
<pre><table id='t2' class='pre'><tr><td><div class="spinner"></div></td></tr></table></pre><br>
|
||||
|
||||
**_(USB Devices)_**
|
||||
|
||||
:sysdevs_usb_devices_help:
|
||||
|
||||
<pre><table id='t3' class='pre'><tr><td><div class="spinner"></div></td></tr></table></pre><br>
|
||||
|
||||
**_(SCSI Devices)_**
|
||||
|
||||
:sysdevs_scsi_devices_help:
|
||||
|
||||
<pre><table id='t4' class='pre'><tr><td><div class="spinner"></div></td></tr></table></pre>
|
||||
<input type="button" value="_(Done)_" onclick="done()">
|
||||
@@ -0,0 +1,239 @@
|
||||
Menu="Flash"
|
||||
Title="Syslinux Configuration"
|
||||
Tag="edit"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$top = $themes1 ? -58 : -44;
|
||||
|
||||
function strip($area) {
|
||||
return preg_replace(["/^|(\n) /","/\n$/"],["$1",""],$area);
|
||||
}
|
||||
$file = '/boot/syslinux/syslinux.cfg';
|
||||
$current = @file_get_contents($file);
|
||||
$default = @file_get_contents("$file-") ?: $current;
|
||||
$current = preg_replace(["/\r\n/","/\r/","/\n$/"],["\n","\n",""],$current);
|
||||
$default = preg_replace(["/\r\n/","/\r/","/\n$/"],["\n","\n",""],$default);
|
||||
|
||||
$title = _('Global Configuration');
|
||||
$menu = 'menu default';
|
||||
$mark = 'label ';
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.switchbutton.css')?>">
|
||||
<style>
|
||||
div.basic{display:block}
|
||||
div.advanced{display:none}
|
||||
textarea.raw{resize:none;font-family:bitstream;width:65.5%}
|
||||
<?
|
||||
switch (strtok($display['theme'],'-')) {
|
||||
case 'gray':
|
||||
case 'azure':
|
||||
echo "span.array,span.system{margin-left:33.33%;width:65.5%;padding:2px 10px;font-weight:bold;border:solid 1px #606E7F;border-bottom:none}\n";
|
||||
echo "textarea.menu{margin-left:33.33%;width:65.5%;margin-bottom:12px;padding:4px 10px;font-family:bitstream;border-top:none}\n";
|
||||
break;
|
||||
case 'white':
|
||||
echo "span.array,span.system{margin-left:33.33%;width:65.5%;padding:2px 10px;font-weight:bold;border:solid 1px #1c1c1c;border-bottom:none}\n";
|
||||
echo "textarea.menu{margin-left:33.33%;width:65.5%;margin-bottom:12px;padding:4px 10px;font-family:bitstream;border:1px solid #1c1b1b;border-top:none}\n";
|
||||
break;
|
||||
case 'black':
|
||||
echo "span.array,span.system{margin-left:33.33%;width:65.5%;padding:2px 10px;font-weight:bold;border:solid 1px #f2f2f2;border-bottom:none}\n";
|
||||
echo "textarea.menu{margin-left:33.33%;width:65.5%;margin-bottom:12px;padding:4px 10px;font-family:bitstream;border:1px solid #f2f2f2;border-top:none}\n";
|
||||
break;
|
||||
}
|
||||
?>
|
||||
</style>
|
||||
<script src="<?autov('/webGui/javascript/jquery.switchbutton.js')?>"></script>
|
||||
<script>
|
||||
const title = '<?=$title?>';
|
||||
const menu = '<?=$menu?>';
|
||||
const mark = '<?=$mark?>';
|
||||
|
||||
Array.prototype.indent = function(o) {
|
||||
if (o) for (var i=0; i < this.length; i++) this[i] = ' '+this[i];
|
||||
return this;
|
||||
};
|
||||
Array.prototype.spliceArray = function(i,n,a) {
|
||||
return Array.prototype.splice.apply(this,[i,n].concat(a));
|
||||
};
|
||||
function prepareMenu(form) {
|
||||
$('input[name="#arg[1]"]').val(form.boot.checked?1:0);
|
||||
if ($('div.basic').is(':visible')) {
|
||||
var label = [], area = [];
|
||||
$(form).find('span[id^=label]').each(function(){
|
||||
label.push($(this).text());
|
||||
});
|
||||
$(form).find('textarea.menu').each(function(i){
|
||||
var start = $('#input-'+i).prop('checked') ? menu+'\n' : '';
|
||||
area.push(start+$(this).val());
|
||||
});
|
||||
var text = [];
|
||||
for (var i=0; i < label.length; i++) {
|
||||
if (i==0) {
|
||||
text.push(area[i]);
|
||||
} else {
|
||||
text.push(mark+label[i]);
|
||||
text.push(area[i].replace(/^|(\n)/g,'$1 '));
|
||||
}
|
||||
}
|
||||
// menu view
|
||||
form.text.value = text.join('\n')+'\n';
|
||||
} else {
|
||||
// raw view
|
||||
form.text.value = form.raw.value+'\n';
|
||||
}
|
||||
form.raw.disabled = true;
|
||||
}
|
||||
function setDefault(form) {
|
||||
var text = <?=json_encode(array_map('strip',explode($mark,$default)))?>;
|
||||
$(form).find('textarea.menu').each(function(i){
|
||||
if (i < text.length) {
|
||||
var area = text[i].split('\n');
|
||||
var label = (i) ? area.shift():title;
|
||||
var start = (area[0]==menu);
|
||||
var checked = start ? ' checked':'';
|
||||
if (i) label += "<span style='float:right'><input type='radio' id='input-"+i+"' title='<?=_('Set default boot menu')?>' onchange='changeMenu(this.form,this.id,true)'"+checked+"></span>";
|
||||
$('#label-'+i).html(label).prop('class',start ? 'array':'system');
|
||||
if (start) area.shift();
|
||||
$(this).val(area.join('\n')).prop('rows',area.length).trigger('change');
|
||||
} else {
|
||||
$('#label-'+i).remove();
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
$(form).find('textarea.raw').val(<?=json_encode($default)?>).prop('rows',$(this).val().match(/\n/g).length+1).trigger('change');
|
||||
}
|
||||
function changeMenu(form,id,update) {
|
||||
$(form).find('input.menu').each(function(){
|
||||
// highlight default boot menu
|
||||
var i = $(this).prop('id');
|
||||
var label = $('#'+i.replace('input','label'));
|
||||
if (i == id) {
|
||||
label.prop('class','array');
|
||||
$(this).prop('checked',true);
|
||||
} else {
|
||||
label.prop('class','system');
|
||||
$(this).prop('checked',false);
|
||||
}
|
||||
});
|
||||
if (update) {
|
||||
// menu view -> update raw view
|
||||
var n = 0, o = null;
|
||||
var x = id.split('-')[1];
|
||||
var text = form.raw.value.split('\n');
|
||||
for (var i=0; i < text.length; i++) {
|
||||
if (text[i].indexOf(mark) >= 0) if (++n == x) o = i + 1;
|
||||
if (text[i].indexOf(menu) >= 0) text.splice(i,1);
|
||||
}
|
||||
if (o) text.splice(o,0,' '+menu);
|
||||
$(form).find('textarea.raw').val(text.join('\n')).prop('rows',text.length);
|
||||
}
|
||||
}
|
||||
$(function(){
|
||||
$('form').find('textarea').each(function(){$(this).on('input change',function(event){
|
||||
$(this).prop('rows',($(this).val().match(/\n/g)||[]).length+1);
|
||||
if (event.type == 'input') return;
|
||||
// propogate changes to 'other' view mode
|
||||
var form = $(this).closest('form');
|
||||
if ($(this).prop('class')=='menu') {
|
||||
// menu view -> update raw view
|
||||
var n = 0, o = 0, x = null;
|
||||
var id = $(this).prop('id').split('-')[1];
|
||||
var area = $(this).val().split('\n');
|
||||
var raw = form.find('textarea.raw');
|
||||
var text = raw.val().split('\n');
|
||||
for (var i=0; i < text.length; i++) {
|
||||
if (text[i].indexOf(mark) >= 0) {
|
||||
if (n++ == id) x = i; else o = i + 1;
|
||||
}
|
||||
if (text[i].indexOf(menu) >= 0) o++;
|
||||
if (x) break;
|
||||
}
|
||||
text.spliceArray(o,(x||text.length)-o,area.indent(o));
|
||||
raw.val(text.join('\n')).prop('rows',text.length);
|
||||
} else {
|
||||
// raw view -> update menu view
|
||||
var n = 0, id = null, area = [];
|
||||
var text = $(this).val().split('\n');
|
||||
for (var i=0; i < text.length; i++) {
|
||||
if (text[i].indexOf(mark) >= 0) {
|
||||
$('#menu-'+(n++)).val(area.join('\n')).prop('rows',area.length);
|
||||
var label = $('#label-'+n);
|
||||
label.html(label.html().replace(/^.*(<span.*)/,text[i].replace(mark,'')+'$1'));
|
||||
area = [];
|
||||
} else {
|
||||
if (text[i].indexOf(menu) >= 0) id = 'input-'+n; else if (text[i].length) area.push(text[i].replace(/^ /,''));
|
||||
}
|
||||
}
|
||||
$('#menu-'+n).val(area.join('\n')).prop('rows',area.length);
|
||||
if (id) changeMenu(form,id,false);
|
||||
}
|
||||
});});
|
||||
if ($.cookie('syslinux_viewmode')=='advanced') {
|
||||
$('.advanced').show();
|
||||
$('.basic').hide();
|
||||
}
|
||||
$('.advancedview').switchButton({
|
||||
labels_placement: 'left',
|
||||
off_label: "_(Menu View)_",
|
||||
on_label: "_(Raw View)_",
|
||||
checked: $.cookie('syslinux_viewmode')=='advanced'
|
||||
});
|
||||
$('.advancedview').change(function() {
|
||||
$('.advanced').toggle('slow');
|
||||
$('.basic').toggle('slow');
|
||||
$.cookie('syslinux_viewmode', $('.advancedview').is(':checked') ? 'advanced':'basic', {expires:3650});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<span class="status" style="margin-top:<?=$top?>px"><input type="checkbox" class="advancedview"></span>
|
||||
|
||||
:syslinux_cfg_help:
|
||||
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareMenu(this)">
|
||||
<input type="hidden" name="#include" value="/webGui/include/update.file.php">
|
||||
<input type="hidden" name="#file" value="<?=$file;?>">
|
||||
<input type="hidden" name="#command" value="/webGui/scripts/bootmode">
|
||||
<input type="hidden" name="#arg[1]" value="">
|
||||
<input type="hidden" name="text" value="">
|
||||
<div markdown="1" class="basic">
|
||||
_(Syslinux configuration)_:
|
||||
: <?$i=0;
|
||||
foreach (array_map('strip',explode($mark,$current)) as $area):
|
||||
$area = explode("\n", $area);
|
||||
$label = ($i) ? array_shift($area):$title;
|
||||
$start = in_array($menu,$area);
|
||||
if ($start) unset($area[array_search($menu,$area)]);
|
||||
?><span id="label-<?=$i?>" class="<?=$start?'array':'system'?>"><?=$label?>
|
||||
<?if ($i):?><span style="float:right"><input type="radio" id="input-<?=$i?>" class="menu" <?=$start?'checked':''?> title="_(Set default boot menu)_" onchange="changeMenu(this.form,this.id,true)"></span><?endif;?></span>
|
||||
<textarea class="menu" id="menu-<?=$i++?>" spellcheck="false" cols="80" rows="<?=count($area)?>" maxlength="2048"><?=implode("\n",$area)?></textarea>
|
||||
<?endforeach;?>
|
||||
|
||||
</div>
|
||||
<div markdown="1" class="advanced">
|
||||
_(Syslinux configuration)_:
|
||||
: <textarea class="raw" name="raw" spellcheck="false" cols="80" rows="<?=substr_count($current,"\n")+1?>" maxlength="2048"><?=$current?></textarea>
|
||||
|
||||
</div>
|
||||
_(Server boot mode)_:
|
||||
: <?=is_dir('/sys/firmware/efi') ? 'UEFI' : 'Legacy'?>
|
||||
|
||||
_(Permit UEFI boot mode)_ <input type="checkbox" name="boot" <?=is_dir('/boot/EFI')?'checked':''?>>
|
||||
: *_(Boot system in UEFI mode)_. _(Please check your system settings to support UEFI boot mode)_.*
|
||||
|
||||
<input type="button" value="_(Default)_" onclick="setDefault(this.form)">
|
||||
: <input type="submit" value="_(Apply)_"><input type="button" value="_(Done)_" onclick="done()">
|
||||
|
||||
:syslinux_button_help:
|
||||
|
||||
</form>
|
||||
@@ -0,0 +1,118 @@
|
||||
Menu="UNRAID-OS"
|
||||
Title="System Log"
|
||||
Icon="icon-log"
|
||||
Tag="list"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$zip = htmlspecialchars(str_replace(' ','_',strtolower($var['NAME'])));
|
||||
$log = '/var/log/syslog';
|
||||
$cfg = '/boot/config/rsyslog.cfg';
|
||||
$max = 5000;
|
||||
$select = [];
|
||||
if (file_exists($cfg)) {
|
||||
$syslog = parse_ini_file($cfg);
|
||||
if (isset($syslog['local_server']) && isset($syslog['server_folder']) && $logs = glob($syslog['server_folder'].'/syslog-*.log',GLOB_NOSORT)) {
|
||||
natsort($logs);
|
||||
$select[] = "<select onchange='showLog(this.value)'>";
|
||||
$select[] = mk_option(1,$log,'syslog');
|
||||
foreach ($logs as $file) $select[] = mk_option(1,$file,basename($file));
|
||||
$select[] = "</select>";
|
||||
}
|
||||
}
|
||||
$select = implode($select);
|
||||
?>
|
||||
<style>
|
||||
input#max{border:none;width:60px;margin:0;padding:0}
|
||||
</style>
|
||||
<script>
|
||||
var logfile = "<?=$log?>";
|
||||
|
||||
function zipfile(){
|
||||
var d = new Date();
|
||||
return "<?=$zip?>-"+logfile.split('/').reverse()[0].replace('.log','')+'-'+d.toISOString().substr(0,16).replace(/[-:]/g,'').replace('T','-')+'.zip';
|
||||
}
|
||||
function cleanUp(file) {
|
||||
if (document.hasFocus()) {
|
||||
$('input#download').val("_(Download)_").prop('disabled',false);
|
||||
$.post('/webGui/include/Download.php',{cmd:'delete',file:file});
|
||||
} else {
|
||||
setTimeout(function(){cleanUp(file);},2000);
|
||||
}
|
||||
}
|
||||
function syslog(file) {
|
||||
$('input#download').val("_(Downloading)_...").prop('disabled',true);
|
||||
$.post('/webGui/include/Download.php',{cmd:'save',source:logfile,file:file},function(zip) {
|
||||
location = zip;
|
||||
setTimeout(function(){cleanUp(file);},4000);
|
||||
});
|
||||
}
|
||||
function highlight(checked,line) {
|
||||
var o = checked ? '-' : '';
|
||||
var n = ($('span.text').css('display')=='none' && !checked) ? 'none' : '';
|
||||
switch (line) {
|
||||
case 'E': $('span.'+o+'error').css('display',n); $('span.error'+o).toggleClass('error -error error-'); break;
|
||||
case 'W': $('span.'+o+'warn').css('display',n); $('span.warn'+o).toggleClass('warn -warn warn-'); break;
|
||||
case 'S': $('span.'+o+'system').css('display',n); $('span.system'+o).toggleClass('system -system system-'); break;
|
||||
case 'A': $('span.'+o+'array').css('display',n); $('span.array'+o).toggleClass('array -array array-'); break;
|
||||
case 'L': $('span.'+o+'login').css('display',n); $('span.login'+o).toggleClass('login -login login-'); break;
|
||||
case 'N': $('span.text,span[class^="-"]').css('display',checked ? 'none':''); break;
|
||||
}
|
||||
$('span.label').show();
|
||||
}
|
||||
function toggle(checked) {
|
||||
highlight(checked,'E');
|
||||
highlight(checked,'W');
|
||||
highlight(checked,'S');
|
||||
highlight(checked,'A');
|
||||
highlight(checked,'L');
|
||||
$('span.label input[type=checkbox]').not('.ctrl').prop('checked',checked);
|
||||
}
|
||||
<?if (_var($display,'resize')):?>
|
||||
function resize() {
|
||||
$('pre.up').height(Math.max(window.innerHeight-320,330));
|
||||
}
|
||||
<?endif;?>
|
||||
function showLog(log) {
|
||||
logfile = log;
|
||||
$('span.label input[type=checkbox]').prop('checked',true);
|
||||
$('span.label').each(function(){
|
||||
var type = $(this).attr('class').replace('label','').replace(/-/g,'');
|
||||
$(this).removeClass().addClass(type+' label');
|
||||
});
|
||||
timers.syslog = setTimeout(function(){$('div.spinner.fixed').show('slow');},500);
|
||||
$.post('/webGui/include/Syslog.php',{log:log,max:$('#max').val()||<?=$max?>},function(data){
|
||||
clearTimeout(timers.syslog);
|
||||
$('pre.up').html(data);
|
||||
$('div.spinner.fixed').hide('slow');
|
||||
});
|
||||
}
|
||||
$(function() {
|
||||
$('input#max').on('keydown',function(e) {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
e.stopImmediatePropagation();
|
||||
showLog(logfile);
|
||||
}
|
||||
});
|
||||
<?if (_var($display,'resize')):?>
|
||||
resize();
|
||||
$(window).bind('resize',function(){resize();});
|
||||
<?endif;?>
|
||||
showLog(logfile);
|
||||
});
|
||||
$('.tabs').append("<span class='status'><span class='lite label'>_(Log size)_: <input type='number' id='max' value='' placeholder='<?=$max?>'></span><?=$select?><span class='lite label'><label>_(Text)_<input type='checkbox' class='ctrl' onclick='highlight(!this.checked,\"N\")' checked></label></span><span class='error label'><label>_(Error)_<input type='checkbox' onclick='highlight(this.checked,\"E\")' checked></label></span><span class='warn label'><label>_(Warning)_<input type='checkbox' onclick='highlight(this.checked,\"W\")' checked></label></span><span class='system label'><label>_(System)_<input type='checkbox' onclick='highlight(this.checked,\"S\")' checked></label></span><span class='array label'><label>_(Array)_<input type='checkbox' onclick='highlight(this.checked,\"A\")' checked></label></span><span class='login label'><label>_(Login)_<input type='checkbox' onclick='highlight(this.checked,\"L\")' checked></label></span><span class='lite label'><input type='checkbox' class='ctrl' onclick='toggle(this.checked)' checked></span></span>");
|
||||
</script>
|
||||
<pre class='up'></pre>
|
||||
<input type="button" id="download" value="_(Download)_" onclick="syslog(zipfile())"><input type="button" value="_(Refresh)_" onclick="showLog(logfile)"><input type="button" value="_(Done)_" onclick="done()">
|
||||
@@ -0,0 +1,171 @@
|
||||
Menu="NetworkServices"
|
||||
Title="Syslog Server"
|
||||
Icon="icon-eula"
|
||||
Tag="file-text-o"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$syslog = @parse_ini_file('/boot/config/rsyslog.cfg') ?: [];
|
||||
|
||||
function plain($ip) {
|
||||
return str_replace(['[',']'],'',$ip);
|
||||
}
|
||||
// Get ports in use
|
||||
$portsInUse = [];
|
||||
exec("lsof -Pni|awk '/LISTEN/ && \$9!~/127.0.0.1/ && \$9!~/\\[::1\\]/{print \$9}'|sort -u", $output);
|
||||
|
||||
$ethX = 'eth0';
|
||||
$addr = ipaddr($ethX);
|
||||
$bind = _var($var,'BIND_MGT')=='yes';
|
||||
$list = ['*',$addr];
|
||||
|
||||
foreach ($output as $line) {
|
||||
[$ip, $port] = my_explode(':', $line);
|
||||
if (!in_array($port,$portsInUse) && (!$bind || in_array(plain($ip),$list))) $portsInUse[] = $port;
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
span.span{display:inline-block;width:224px}
|
||||
</style>
|
||||
<script>
|
||||
function localFolder(local,time) {
|
||||
if (local) $('#local_folder').show(time); else $('#local_folder').hide(time);
|
||||
}
|
||||
function logOptions(log,time) {
|
||||
if (log) $('#log_options').show(time); else $('#log_options').hide(time);
|
||||
}
|
||||
|
||||
$(function(){
|
||||
localFolder(document.syslog.local_server.value);
|
||||
logOptions(document.syslog.log_rotation.value);
|
||||
});
|
||||
function validatePort(form) {
|
||||
var portsInUse = JSON.parse('<?=json_encode($portsInUse)?>');
|
||||
var currentPort = "<?=(_var($syslog,'local_server') && _var($syslog,'server_protocol')!='udp') ? _var($syslog,'server_port',514) : 514?>";
|
||||
var port = $(form).find('input[name="server_port"]');
|
||||
var remotePort = $(form).find('input[name="remote_port"]');
|
||||
var protocol = $(form).find('select[name="server_protocol"]').val();
|
||||
if ( !port.val() ) port.val("514");
|
||||
port.val(parseInt(port.val()));
|
||||
remotePort.val(parseInt(remotePort.val()));
|
||||
var newport = port.val();
|
||||
if (newport != currentPort && protocol != "udp" && $(form).find('select[name="local_server"]').val()) {
|
||||
if (portsInUse.includes(newport)) {
|
||||
swal({title:'_(Port already in use)_',text:sprintf('_(Port %s is already in use by other services)_',newport),type:'error',showCancelButton:false,confirmButtonText:"_(OK)_"});
|
||||
return;
|
||||
}
|
||||
}
|
||||
var list = [];
|
||||
if (newport < 1 || newport > 65535) {
|
||||
list.push("_(Local syslog port)_");
|
||||
}
|
||||
var remote = remotePort.val();
|
||||
if (!remote) remote = 514;
|
||||
if (remote < 1 || remote > 65535) {
|
||||
list.push("_(Remote syslog port)_");
|
||||
}
|
||||
if (list.length > 0) {
|
||||
swal({title:'_(Port out of range)_',text:sprintf('_(%s is out of range (minimum 1 maximum 65535))_',list.join(", ")),type:'error',showCancelButton:false,confirmButtonText:"_(OK)_"});
|
||||
return;
|
||||
}
|
||||
form.submit();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<form markdown="1" name="syslog" method="POST" action="/update.php" target="progressFrame">
|
||||
<input type="hidden" name="#file" value="/boot/config/rsyslog.cfg">
|
||||
<input type="hidden" name="#command" value="/webGui/scripts/rsyslog_config">
|
||||
|
||||
_(Local syslog server)_:
|
||||
: <span class="span"><select name="local_server" onchange="localFolder(this.value,'slow')">
|
||||
<?=mk_option(_var($syslog,'local_server'), "", _("Disabled"))?>
|
||||
<?=mk_option(_var($syslog,'local_server'), "1", _("Enabled"))?>
|
||||
</select></span>
|
||||
<select name="server_protocol" class="narrow">
|
||||
<?=mk_option(_var($syslog,'server_protocol'), "udp", _("UDP"))?>
|
||||
<?=mk_option(_var($syslog,'server_protocol'), "tcp", _("TCP"))?>
|
||||
<?=mk_option(_var($syslog,'server_protocol'), "both", _("Both"))?>
|
||||
</select>
|
||||
<input type="text" name="server_port" class="trim" value="<?=_var($syslog,'server_port')?>" maxlength="5" placeholder="514">
|
||||
|
||||
:syslog_local_server_help:
|
||||
|
||||
<div markdown="1" id="local_folder" style="display:none">
|
||||
_(Local syslog folder)_:
|
||||
: <select name="server_folder">
|
||||
<?=mk_option(0,'','<'._('custom').'>','disabled')?>
|
||||
<?foreach ($shares as $share){echo mk_option(_var($syslog,'server_folder'), '/mnt/user/'.$share['name'], $share['name']);}?>
|
||||
</select>
|
||||
|
||||
:syslog_local_folder_help:
|
||||
|
||||
_(Local syslog rotation)_:
|
||||
: <select name="log_rotation" onchange="logOptions(this.value,'slow')">
|
||||
<?=mk_option(_var($syslog,'log_rotation'), "", _("Disabled"))?>
|
||||
<?=mk_option(_var($syslog,'log_rotation'), "1", _("Enabled"))?>
|
||||
</select>
|
||||
|
||||
:syslog_local_rotation_help:
|
||||
|
||||
<div markdown="1" id="log_options" style="display:none">
|
||||
_(Local syslog maximum file size)_:
|
||||
: <select name="log_size">
|
||||
<?=mk_option(_var($syslog,'log_size'), '1M', '1 '._('MB'))?>
|
||||
<?=mk_option(_var($syslog,'log_size'), '2M', '2 '._('MB'))?>
|
||||
<?=mk_option(_var($syslog,'log_size'), '5M', '5 '._('MB'))?>
|
||||
<?=mk_option(_var($syslog,'log_size'), '10M', '10 '._('MB'))?>
|
||||
<?=mk_option(_var($syslog,'log_size'), '20M', '20 '._('MB'))?>
|
||||
<?=mk_option(_var($syslog,'log_size'), '50M', '50 '._('MB'))?>
|
||||
<?=mk_option(_var($syslog,'log_size'), '100M', '100 '._('MB'))?>
|
||||
<?=mk_option(_var($syslog,'log_size'), '200M', '200 '._('MB'))?>
|
||||
<?=mk_option(_var($syslog,'log_size'), '500M', '500 '._('MB'))?>
|
||||
</select>
|
||||
|
||||
:syslog_local_file_size_help:
|
||||
|
||||
_(Local syslog number of files)_:
|
||||
: <select name="log_files">
|
||||
<?=mk_option(_var($syslog,'log_files'), '1', '1')?>
|
||||
<?=mk_option(_var($syslog,'log_files'), '2', '2')?>
|
||||
<?=mk_option(_var($syslog,'log_files'), '3', '3')?>
|
||||
<?=mk_option(_var($syslog,'log_files'), '4', '4')?>
|
||||
</select>
|
||||
|
||||
:syslog_local_file_number_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
_(Remote syslog server)_:
|
||||
: <span class="span"><input type="text" name="remote_server" class="narrow" value="<?=_var($syslog,'remote_server')?>" maxlength="23" placeholder="_(name or ip address)_"></span>
|
||||
<select name="remote_protocol" class="narrow" size="1">
|
||||
<?=mk_option(_var($syslog,'remote_protocol'), "udp", _("UDP"))?>
|
||||
<?=mk_option(_var($syslog,'remote_protocol'), "tcp", _("TCP"))?>
|
||||
</select>
|
||||
<input type="number" name="remote_port" class="trim" value="<?=_var($syslog,'remote_port')?>" maxlength="5" placeholder="514" pattern="([0-9]{1,5})">
|
||||
|
||||
:syslog_remote_server_help:
|
||||
|
||||
_(Mirror syslog to flash)_:
|
||||
: <select name="syslog_flash" size="1">
|
||||
<?=mk_option(_var($syslog,'syslog_flash'), "", _("No"))?>
|
||||
<?=mk_option(_var($syslog,'syslog_flash'), "1", _("Yes"))?>
|
||||
</select>
|
||||
|
||||
:syslog_mirror_flash_help:
|
||||
|
||||
|
||||
: <input type="button" value="_(Apply)_" onclick='validatePort(this.form)' disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
@@ -0,0 +1,23 @@
|
||||
Menu="Buttons:3"
|
||||
Title="Terminal"
|
||||
Icon="icon-u-terminal"
|
||||
Code="e93f"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
* Copyright 2012-2021, 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.
|
||||
*/
|
||||
?>
|
||||
<script>
|
||||
function TerminalButton() {
|
||||
var d = new Date();
|
||||
openTerminal('ttyd','Web Terminal '+d.getTime(),'');
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,4 @@
|
||||
Menu="Tasks:90"
|
||||
Type="xmenu"
|
||||
Tabs="false"
|
||||
Code="e909"
|
||||
@@ -0,0 +1,127 @@
|
||||
Menu="Scheduler"
|
||||
Title="TRIM Settings"
|
||||
Tag="superpowers"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$mode = ['Disabled','Hourly','Daily','Weekly','Monthly'];
|
||||
$days = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
|
||||
?>
|
||||
<script>
|
||||
function trimNow() {
|
||||
openPlugin("ssd_trim", "_(Perform TRIM Operation)_");
|
||||
}
|
||||
function presetTrim(form) {
|
||||
var mode = form.mode.value;
|
||||
form.min.disabled = mode==0;
|
||||
form.day.disabled = mode==0 || mode!=3;
|
||||
form.dotm.disabled = mode==0 || mode!=4;
|
||||
form.hour1.disabled = mode==0;
|
||||
form.hour2.disabled = mode==0;
|
||||
form.day.value = form.day.disabled ? '*' : (form.day.value=='*' ? 0 : form.day.value);
|
||||
form.dotm.value = form.dotm.disabled ? '*' : (form.dotm.value=='*' ? 1 : form.dotm.value);
|
||||
if (mode==1) {$('#hour1').hide(); $('#hour2').show();} else {$('#hour2').hide(); $('#hour1').show();}
|
||||
}
|
||||
function prepareTrim(form) {
|
||||
var include = [];
|
||||
var mode = form.mode.value;
|
||||
form.hour.value = mode!=1 ? form.hour1.value : form.hour2.value;
|
||||
form.min.value = mode!=1 ? form.min.value : 0;
|
||||
form.hour1.disabled = true;
|
||||
form.hour2.disabled = true;
|
||||
for (var i=0,item; item=form.disk.options[i]; i++) {
|
||||
if (item.selected) {
|
||||
include.push(item.value);
|
||||
item.selected = false;
|
||||
}
|
||||
}
|
||||
item = form.disk.options[0];
|
||||
item.value = include.join(',');
|
||||
item.selected = true;
|
||||
}
|
||||
$(function() {
|
||||
presetTrim(document.trim_schedule);
|
||||
});
|
||||
</script>
|
||||
<form markdown="1" name="trim_schedule" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareTrim(this)">
|
||||
<input type="hidden" name="#file" value="dynamix/dynamix.cfg">
|
||||
<input type="hidden" name="#section" value="ssd">
|
||||
<input type="hidden" name="#include" value="/webGui/include/update.trim.php">
|
||||
<input type="hidden" name="hour" value="">
|
||||
_(TRIM schedule)_:
|
||||
: <select name="mode" onchange="presetTrim(this.form)">
|
||||
<?for ($m=0; $m<count($mode); $m++):?>
|
||||
<?=mk_option(_var($ssd,'mode'), strval($m), _($mode[$m]))?>
|
||||
<?endfor;?>
|
||||
</select>
|
||||
|
||||
:trim_schedule_plug:
|
||||
> Choose a trim schedule ranging from hourly, daily, weekly and monthly.
|
||||
>
|
||||
> The interval determines how often SSD trim will run, it runs in the background.
|
||||
:end
|
||||
|
||||
_(Day of the week)_:
|
||||
: <select name="day">
|
||||
<?for ($d=0; $d<count($days); $d++):?>
|
||||
<?=mk_option(_var($ssd,'day'), strval($d), _($days[$d],0))?>
|
||||
<?endfor;?>
|
||||
<?=mk_option(_var($ssd,'day'), "*", "--------", _("disabled"))?>
|
||||
</select>
|
||||
|
||||
:trim_day_of_the_week_plug:
|
||||
> Choose a day when the weekly schedule is selected. Otherwise disabled.
|
||||
:end
|
||||
|
||||
_(Day of the month)_:
|
||||
: <select name="dotm">
|
||||
<?for ($d=1; $d<=31; $d++):?>
|
||||
<?=mk_option(_var($ssd,'dotm'), strval($d), sprintf("%02d", $d))?>
|
||||
<?endfor;?>
|
||||
<?=mk_option(_var($ssd,'dotm'), "*", "--------", _("disabled"))?>
|
||||
</select>
|
||||
|
||||
:trim_day_of_the_month_plug:
|
||||
> Choose a date when the monthly schedule is selected. Otherwise disabled.
|
||||
:end
|
||||
|
||||
_(Time of the day)_:
|
||||
: <span id="hour1" style="display:none"><select name="hour1" class="narrow">
|
||||
<?for ($d=0; $d<=23; $d++):?>
|
||||
<?=mk_option(_var($ssd,'hour'), strval($d), sprintf("%02d", $d))?>
|
||||
<?endfor;?>
|
||||
</select>
|
||||
<select name="min" class="narrow">
|
||||
<?for ($d=0; $d<=55; $d+=5):?>
|
||||
<?=mk_option(_var($ssd,'min'), strval($d), sprintf("%02d", $d))?>
|
||||
<?endfor;?>
|
||||
</select> _(HH:MM)_</span>
|
||||
: <span id="hour2" style="display:none"><select name="hour2">
|
||||
<?=mk_option(_var($ssd,'hour'), "*/1", _("Every hour"))?>
|
||||
<?=mk_option(_var($ssd,'hour'), "*/2", _("Every 2 hours"))?>
|
||||
<?=mk_option(_var($ssd,'hour'), "*/3", _("Every 3 hours"))?>
|
||||
<?=mk_option(_var($ssd,'hour'), "*/4", _("Every 4 hours"))?>
|
||||
<?=mk_option(_var($ssd,'hour'), "*/6", _("Every 6 hours"))?>
|
||||
<?=mk_option(_var($ssd,'hour'), "*/8", _("Every 8 hours"))?>
|
||||
</select></span>
|
||||
|
||||
:trim_time_of_the_day_plug:
|
||||
> When an hourly schedule is selected this will set the interval in hours. An interval always starts on the whole hour (minute 0).
|
||||
>
|
||||
> For the other schedules choose here the time of the day trim should start.
|
||||
:end
|
||||
|
||||
|
||||
: <input type="submit" name="#apply" value="_(Apply)_"><input type="button" value="_(Done)_" onclick="done()"><input type="button" value="_(Trim Now)_" onclick="trimNow()">
|
||||
</form>
|
||||
@@ -0,0 +1,4 @@
|
||||
Menu="Tools:10"
|
||||
Type="menu"
|
||||
Title="Unraid OS"
|
||||
Tag="lemon-o"
|
||||
@@ -0,0 +1,191 @@
|
||||
Menu="UserList"
|
||||
Title="Add User"
|
||||
Tag="user"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, 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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$void = "<img src='/webGui/images/user.png' width='48' height='48' onclick='$("#drop").click()' style='cursor:pointer' title='"._('Click to select PNG file')."'>";
|
||||
$icon = "<i class='fa fa-trash top' title='"._('Restore default image')."' onclick='restore()'></i>";
|
||||
$zxcvbn = file_exists('/boot/config/plugins/dynamix/zxcvbn.js');
|
||||
?>
|
||||
<style>
|
||||
<?if ($display['theme']=='gray'):?>
|
||||
span#dropbox{border:1px solid #606E7F;border-radius:5px;background:#121510;padding:28px 12px;line-height:72px;margin-right:16px}
|
||||
<?elseif ($display['theme']=='azure'):?>
|
||||
span#dropbox{border:1px solid #606E7F;border-radius:5px;background:#EDEAEF;padding:28px 12px;line-height:72px;margin-right:16px}
|
||||
<?elseif ($display['theme']=='black'):?>
|
||||
span#dropbox{border:1px solid #f2f2f2;border-radius:5px;background:#262626;padding:28px 12px;line-height:72px;margin-right:16px}
|
||||
<?else:?>
|
||||
span#dropbox{border:1px solid #1c1c1c;border-radius:5px;background:#e8e8e8;padding:28px 12px;line-height:72px;margin-right:16px}
|
||||
<?endif;?>
|
||||
i.top{position:absolute;padding-top:4px;cursor:pointer}
|
||||
i#showPass.checked{opacity:0.5}
|
||||
.usage-disk.sys{display:inline-block;width:10rem;top:<?=$themes2?'1.2':'.2'?>rem;margin-left:12px;border-radius:4px}
|
||||
</style>
|
||||
|
||||
<script src="<?autov('/webGui/javascript/jquery.filedrop.js')?>"></script>
|
||||
<?if ($zxcvbn):?>
|
||||
<script src="<?autov('/boot/config/plugins/dynamix/zxcvbn.js')?>" async></script>
|
||||
<?endif;?>
|
||||
<script>
|
||||
var path = '/boot/config/plugins/dynamix/users';
|
||||
var filename = '';
|
||||
|
||||
function base64(str) {
|
||||
return window.btoa(unescape(encodeURIComponent(str)));
|
||||
}
|
||||
function showPassword() {
|
||||
if ($('#showPass').hasClass('checked')) {
|
||||
$('#showPass').removeClass('checked fa-eye-slash').addClass('fa-eye');
|
||||
var type = 'password';
|
||||
} else {
|
||||
$('#showPass').addClass('checked fa-eye-slash').removeClass('fa-eye');
|
||||
var type = 'text';
|
||||
}
|
||||
$('input[name="userPasswordGUI"]').attr('type',type);
|
||||
$('input[name="userPasswordConfGUI"]').attr('type',type);
|
||||
}
|
||||
function checkUsername(form) {
|
||||
var username = form.userName.value.trim();
|
||||
if (!username.match('^[a-z_][a-z0-9_-]*[$]?$')) {
|
||||
$('input[name="cmdUserEdit"]').val("_(Add)_");
|
||||
swal({title:"_(Invalid user name)_",text:"_(Use only lowercase letters, digits, underscores and dashes)_",type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
|
||||
return false;
|
||||
}
|
||||
if (form.userPasswordGUI.value.length > 128 || form.userPasswordConfGUI.value.length > 128) {
|
||||
swal({title:"_(Password too long)_",text:"_(Use a password up to 128 characters)_",type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
if (filename) {
|
||||
$.post("/webGui/include/FileUpload.php",{cmd:'save',path:path,filename:filename,output:username+'.png'});
|
||||
}
|
||||
form.userPassword.value = base64(form.userPasswordGUI.value);
|
||||
form.userPasswordConf.value = base64(form.userPasswordConfGUI.value);
|
||||
form.userPasswordGUI.disabled = true;
|
||||
form.userPasswordConfGUI.disabled = true;
|
||||
return true;
|
||||
}
|
||||
function validatePassword(input) {
|
||||
<?if ($zxcvbn):?>
|
||||
var custom = ['unraid','limetech','lime-technology','bergware','squidly'];
|
||||
var strength = ['Worst','Bad','Weak','Good','Strong'];
|
||||
var emoji = ['😵','😩','😔','😀','😎'];
|
||||
if (!input) {
|
||||
$('#strength-bar').css('background-color','transparent');
|
||||
$('#strength-text').html('');
|
||||
$('.usage-disk.sys').addClass('none');
|
||||
} else {
|
||||
var bar = zxcvbn(input,custom);
|
||||
switch (bar.score) {
|
||||
case 0: $('#strength-bar').css('background-color','red'); break;
|
||||
case 1: $('#strength-bar').css('background-color','yellow'); break;
|
||||
case 2: $('#strength-bar').css('background-color','orange'); break;
|
||||
case 3: $('#strength-bar').css('background-color','blue'); break;
|
||||
case 4: $('#strength-bar').css('background-color','green'); break;
|
||||
}
|
||||
$('#strength-bar').css('width',Math.min(input.length*100/64,100)+'%');
|
||||
$('#strength-text').html(emoji[bar.score]+' '+strength[bar.score]+'. '+bar.feedback.warning);
|
||||
$('.usage-disk.sys').removeClass('none');
|
||||
}
|
||||
<?endif;?>
|
||||
}
|
||||
function restore() {
|
||||
// restore original image
|
||||
$('#dropbox').html("<?=$void?>");
|
||||
filename = '';
|
||||
}
|
||||
$(function(){
|
||||
var dropbox = $('#dropbox');
|
||||
// attach the drag-n-drop feature to the 'dropbox' element
|
||||
dropbox.filedrop({
|
||||
maxfiles:1,
|
||||
maxfilesize:512, // KB
|
||||
url:'/webGui/include/FileUpload.php',
|
||||
data:{path:path,"csrf_token":"<?=$var['csrf_token']?>"},
|
||||
beforeEach:function(file) {
|
||||
if (!file.type.match(/^image\/png/)) {
|
||||
swal({title:"Warning",text:"Only PNG images are allowed!",type:"warning",html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
},
|
||||
error: function(error, file, i) {
|
||||
switch (error) {
|
||||
case 'BrowserNotSupported':
|
||||
swal({title:"_(Browser error)_",text:"_(Your browser does not support HTML5 file uploads)_!",type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
break;
|
||||
case 'TooManyFiles':
|
||||
swal({title:"_(Too many files)_",text:"_(Please select one file only)_!",type:"error",html:true});
|
||||
break;
|
||||
case 'FileTooLarge':
|
||||
swal({title:"_(File too large)_",text:"_(Maximum file upload size is 512K)_ (524,288 _(bytes)_)",type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
break;
|
||||
}
|
||||
},
|
||||
uploadStarted:function(i,file,count) {
|
||||
var image = $('img', $(dropbox));
|
||||
var reader = new FileReader();
|
||||
image.width = 48;
|
||||
image.height = 48;
|
||||
reader.onload = function(e){image.attr('src',e.target.result);};
|
||||
reader.readAsDataURL(file);
|
||||
},
|
||||
uploadFinished:function(i,file,response) {
|
||||
if (response == 'OK 200') {
|
||||
if (!filename) $(dropbox).append("<?=$icon?>");
|
||||
$('input[name="userDesc"]').trigger('change');
|
||||
filename = file.name;
|
||||
} else {
|
||||
swal({title:"_(Upload error)_",text:response,type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
}
|
||||
}
|
||||
});
|
||||
// simulate a drop action when manual file selection is done
|
||||
$('#drop').bind('change', function(e) {
|
||||
var files = e.target.files;
|
||||
if ($('#dropbox').triggerHandler({type:'drop',dataTransfer:{files:files}})==false) e.stopImmediatePropagation();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<form markdown="1" name="user_edit" method="POST" action="/update.htm" target="progressFrame" onsubmit="return checkUsername(this)">
|
||||
_(User name)_:
|
||||
: <input type="text" name="userName" maxlength="40" onKeyUp="this.form.cmdUserEdit.disabled=(this.form.userName.value=='')">
|
||||
|
||||
:user_add_username_help:
|
||||
|
||||
_(Description)_:
|
||||
: <input type="text" name="userDesc" maxlength="64" pattern='[^&:"]*'>
|
||||
|
||||
:user_add_description_help:
|
||||
|
||||
_(Custom image)_:
|
||||
: <span id="dropbox"><?=$void?></span><em>_(Drag-n-drop a PNG file or click the image at the left)_</em><input type="file" id="drop" accept="image/png" style="display:none">
|
||||
|
||||
:user_add_custom_image_help:
|
||||
|
||||
_(Password)_:
|
||||
<input type="hidden" name="userPassword" value="">
|
||||
: <input type="password" name="userPasswordGUI" maxlength="129" autocomplete="new-password" onKeyUp="validatePassword(this.value);this.form.cmdUserEdit.disabled=(this.form.userName.value=='' || this.form.userPasswordGUI.value!=this.form.userPasswordConfGUI.value)">
|
||||
<i id="showPass" class="fa fa-eye" style="cursor:pointer" title="_(Show / Hide password)_" onclick="showPassword()"></i><span><span class="usage-disk sys none"><span id="strength-bar" style="width:0"></span><span></span></span><span id="strength-text"></span></span>
|
||||
|
||||
:user_password_help:
|
||||
|
||||
_(Retype password)_:
|
||||
<input type="hidden" name="userPasswordConf" value="">
|
||||
: <input type="password" name="userPasswordConfGUI" maxlength="129" autocomplete="new-password" onKeyUp="this.form.cmdUserEdit.disabled=(this.form.userName.value=='' || this.form.userPasswordGUI.value!=this.form.userPasswordConfGUI.value)">
|
||||
|
||||
|
||||
: <input type="submit" name="cmdUserEdit" value="_(Add)_" onclick="this.value='Add'" disabled><input type="button" value="_(Done)_" onclick="done('UserAdd')">
|
||||
</form>
|
||||
@@ -0,0 +1,339 @@
|
||||
Menu="UserList"
|
||||
Title="Edit User"
|
||||
Tag="user"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
* Copyright 2012-2021, 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.
|
||||
*/
|
||||
?>
|
||||
<?if (!array_key_exists($name, $users)):?>
|
||||
<p class="notice"><?=sprintf(_('User %s has been deleted'),htmlspecialchars($name))?>.</p><br>
|
||||
<input type="button" value="_(Done)_" onClick="done()">
|
||||
<?return;?>
|
||||
<?endif;?>
|
||||
<?
|
||||
$user = "/boot/config/plugins/dynamix/users/$name.png";
|
||||
$void = "<img src='/webGui/images/user.png' width='48' height='48' id='image' onclick='$("#drop").click()' style='cursor:pointer' title='"._('Click to select PNG file')."'>";
|
||||
$icon = "<i class='fa fa-trash top' title='"._('Restore default image')."' onclick='restore()'></i>";
|
||||
$zxcvbn = file_exists('/boot/config/plugins/dynamix/zxcvbn.js');
|
||||
|
||||
$file = "/boot/config/ssh/root/authorized_keys";
|
||||
$text = preg_replace(["/\r\n/","/\r/"],"\n", @file_get_contents($file) ?: '');
|
||||
?>
|
||||
<style>
|
||||
<?if ($display['theme']=='gray'):?>
|
||||
span#dropbox{border:1px solid #606E7F;border-radius:5px;background:#121510;padding:28px 12px;line-height:72px;margin-right:16px}
|
||||
<?elseif ($display['theme']=='azure'):?>
|
||||
span#dropbox{border:1px solid #606E7F;border-radius:5px;background:#EDEAEF;padding:28px 12px;line-height:72px;margin-right:16px}
|
||||
<?elseif ($display['theme']=='black'):?>
|
||||
span#dropbox{border:1px solid #f2f2f2;border-radius:5px;background:#262626;padding:28px 12px;line-height:72px;margin-right:16px}
|
||||
<?else:?>
|
||||
span#dropbox{border:1px solid #1c1c1c;border-radius:5px;background:#e8e8e8;padding:28px 12px;line-height:72px;margin-right:16px}
|
||||
<?endif;?>
|
||||
i.top{position:absolute;padding-top:4px;cursor:pointer}
|
||||
i#showPass.checked{opacity:0.5}
|
||||
.usage-disk.sys{display:inline-block;width:10rem;top:<?=$themes2?'1.2':'.2'?>rem;margin-left:12px;border-radius:4px}
|
||||
</style>
|
||||
|
||||
<script src="<?autov('/webGui/javascript/jquery.filedrop.js')?>"></script>
|
||||
<?if ($zxcvbn):?>
|
||||
<script src="<?autov('/boot/config/plugins/dynamix/zxcvbn.js')?>" async></script>
|
||||
<?endif;?>
|
||||
<script>
|
||||
var path = '/boot/config/plugins/dynamix/users';
|
||||
var filename = '';
|
||||
|
||||
function base64(str) {
|
||||
return window.btoa(unescape(encodeURIComponent(str)));
|
||||
}
|
||||
function showPassword() {
|
||||
if ($('#showPass').hasClass('checked')) {
|
||||
$('#showPass').removeClass('checked fa-eye-slash').addClass('fa-eye');
|
||||
var type = 'password';
|
||||
} else {
|
||||
$('#showPass').addClass('checked fa-eye-slash').removeClass('fa-eye');
|
||||
var type = 'text';
|
||||
}
|
||||
$('input[name="userPasswordGUI"]').attr('type',type);
|
||||
$('input[name="userPasswordConfGUI"]').attr('type',type);
|
||||
}
|
||||
function checkPassword(form) {
|
||||
if (form.userPasswordGUI.value.length > 128 || form.userPasswordConfGUI.value.length > 128) {
|
||||
swal({title:"_(Password too long)_",text:"_(Use a password up to 128 characters)_",type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
form.userPassword.value = base64(form.userPasswordGUI.value);
|
||||
form.userPasswordConf.value = base64(form.userPasswordConfGUI.value);
|
||||
form.userPasswordGUI.disabled = true;
|
||||
form.userPasswordConfGUI.disabled = true;
|
||||
return true;
|
||||
}
|
||||
function validatePassword(input) {
|
||||
<?if ($zxcvbn):?>
|
||||
var custom = ['unraid','limetech','lime-technology','bergware','squidly'];
|
||||
var strength = ['Worst','Bad','Weak','Good','Strong'];
|
||||
var emoji = ['😵','😩','😔','😀','😎'];
|
||||
if (!input) {
|
||||
$('#strength-bar').css('background-color','transparent');
|
||||
$('#strength-text').html('');
|
||||
$('.usage-disk.sys').addClass('none');
|
||||
} else {
|
||||
var bar = zxcvbn(input,custom);
|
||||
switch (bar.score) {
|
||||
case 0: $('#strength-bar').css('background-color','red'); break;
|
||||
case 1: $('#strength-bar').css('background-color','yellow'); break;
|
||||
case 2: $('#strength-bar').css('background-color','orange'); break;
|
||||
case 3: $('#strength-bar').css('background-color','blue'); break;
|
||||
case 4: $('#strength-bar').css('background-color','green'); break;
|
||||
}
|
||||
$('#strength-bar').css('width',Math.min(input.length*100/64,100)+'%');
|
||||
$('#strength-text').html(emoji[bar.score]+' '+strength[bar.score]+'. '+bar.feedback.warning);
|
||||
$('.usage-disk.sys').removeClass('none');
|
||||
}
|
||||
<?endif;?>
|
||||
}
|
||||
function restore() {
|
||||
// restore original image and activate APPLY button
|
||||
$('#dropbox').html("<?=$void?>");
|
||||
$('input[name="userDesc"]').trigger('change');
|
||||
filename = 'reset';
|
||||
}
|
||||
function upload(remove) {
|
||||
// save or delete upload when APPLY is pressed
|
||||
if (remove || filename=='reset') {
|
||||
$.post("/webGui/include/FileUpload.php",{cmd:'delete',path:path,filename:'<?=addslashes(htmlspecialchars($name))?>.png'});
|
||||
} else if (filename) {
|
||||
$.post("/webGui/include/FileUpload.php",{cmd:'save',path:path,filename:filename,output:'<?=addslashes(htmlspecialchars($name))?>.png'});
|
||||
}
|
||||
}
|
||||
function checkKey(form) {
|
||||
// check syntax of ssh keys
|
||||
var rows = form.text.value.split('\n');
|
||||
for (var i=0,row; row=rows[i]; i++) {
|
||||
if (row.search(/^(ssh-ed25519 AAAAC3NzaC1lZDI1NTE5|sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29t|ssh-rsa AAAAB3NzaC1yc2)[0-9A-Za-z+/]+[=]{0,3}(\s.*)?$/)==-1) {
|
||||
swal({title:"_(Invalid Key)_",text:"["+(i+1)+"] "+row.split(' ')[0]+": _(Syntax of the key is incorrect)_!",type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
$(function(){
|
||||
var dropbox = $('#dropbox');
|
||||
// attach the drag-n-drop feature to the 'dropbox' element
|
||||
dropbox.filedrop({
|
||||
maxfiles:1,
|
||||
maxfilesize:512, // KB
|
||||
url:'/webGui/include/FileUpload.php',
|
||||
data:{"csrf_token":"<?=$var['csrf_token']?>"},
|
||||
beforeEach:function(file) {
|
||||
if (!file.type.match(/^image\/png/)) {
|
||||
swal({title:"Warning",text:"_(Only PNG images are allowed)_!",type:"warning",html:true,confirmButtonText:"_(Ok)_"});
|
||||
return false;
|
||||
}
|
||||
},
|
||||
error: function(error, file, i) {
|
||||
switch (error) {
|
||||
case 'BrowserNotSupported':
|
||||
swal({title:"_(Browser error)_",text:"_(Your browser does not support HTML5 file uploads)_!",type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
break;
|
||||
case 'TooManyFiles':
|
||||
swal({title:"_(Too many files)_",text:"_(Please select one file only)_!",html:true,type:"error"});
|
||||
break;
|
||||
case 'FileTooLarge':
|
||||
swal({title:"_(File too large)_",text:"_(Maximum file upload size is 512K)_ (524,288 _(bytes)_)",type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
break;
|
||||
}
|
||||
},
|
||||
uploadStarted:function(i,file,count) {
|
||||
var image = $('img', $(dropbox));
|
||||
var reader = new FileReader();
|
||||
image.width = 48;
|
||||
image.height = 48;
|
||||
reader.onload = function(e){image.attr('src',e.target.result);};
|
||||
reader.readAsDataURL(file);
|
||||
},
|
||||
uploadFinished:function(i,file,response) {
|
||||
if (response == 'OK 200') {
|
||||
if (!filename || filename=='reset') $(dropbox).append("<?=$icon?>");
|
||||
$('input[name="userDesc"]').trigger('change');
|
||||
filename = file.name;
|
||||
} else {
|
||||
swal({title:"_(Upload error)_",text:response,type:"error",html:true,confirmButtonText:"_(Ok)_"});
|
||||
}
|
||||
}
|
||||
});
|
||||
// simulate a drop action when manual file selection is done
|
||||
$('#drop').bind('change', function(e) {
|
||||
var files = e.target.files;
|
||||
if ($('#dropbox').triggerHandler({type:'drop',dataTransfer:{files:files}})==false) e.stopImmediatePropagation();
|
||||
});
|
||||
// auto size the textarea
|
||||
$('form').find('textarea').on('input change',function(){
|
||||
$(this).prop('rows',Math.max(($(this).val().match(/\n/g)||[]).length+1,10));
|
||||
$('form').find('input[value="_(Save)_"]').prop('disabled',false);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<div class="spinner fixed"></div>
|
||||
<form markdown="1" method="POST" action="/update.htm" target="progressFrame" onsubmit="upload(<?=$name=="root" ? 'false' : 'this.confirmDelete.checked'?>)">
|
||||
<input type="hidden" name="userName" value="<?=htmlspecialchars($name)?>">
|
||||
_(User name)_:
|
||||
: <?=htmlspecialchars($name)?>
|
||||
|
||||
_(Description)_:
|
||||
: <input type="text" name="userDesc" maxlength="64" value="<?=htmlspecialchars($users[$name]['desc'])?>" pattern='[^&:"]*'>
|
||||
|
||||
:user_edit_description_help:
|
||||
|
||||
_(Custom image)_:
|
||||
: <span id="dropbox">
|
||||
<?if (file_exists($user)):?>
|
||||
<img src="<?=autov($user)?>" id="image" width="48" height="48" onclick="$('#drop').click()" style="cursor:pointer" title="_(Click to select PNG file)_"><?=$icon?>
|
||||
<?else:?>
|
||||
<?=$void?>
|
||||
<?endif;?>
|
||||
</span><em>_(Drag-n-drop a PNG file or click the image at the left)_</em><input type="file" id="drop" accept="image/png" style="display:none">
|
||||
|
||||
:user_edit_custom_image_help:
|
||||
|
||||
<?if ($name=="root"):?>
|
||||
|
||||
<?else:?>
|
||||
_(Delete)_<input type="checkbox" name="confirmDelete" onChange="chkDelete(this.form, this.form.cmdUserEdit)">
|
||||
<?endif;?>
|
||||
: <input type="submit" name="cmdUserEdit" value="_(Apply)_" onclick="if (this.value=='_(Delete)_') this.value='Delete'; else this.value='Apply';" disabled><input type="button" value="_(Done)_" onclick="done('UserEdit')">
|
||||
</form>
|
||||
<br><br>
|
||||
<form markdown="1" method="POST" action="/update.htm" onsubmit="return checkPassword(this)" target="progressFrame">
|
||||
<input type="hidden" name="userName" value="<?=htmlspecialchars($name)?>">
|
||||
_(Password)_:
|
||||
<input type="hidden" name="userPassword" value="">
|
||||
: <input type="password" name="userPasswordGUI" maxlength="129" autocomplete="new-password" onKeyUp="validatePassword(this.value);this.form.cmdUserEdit.disabled=(this.form.userPasswordGUI.value != this.form.userPasswordConfGUI.value);">
|
||||
<i id="showPass" class="fa fa-eye" style="cursor:pointer" title="_(Show / Hide password)_" onclick="showPassword()"></i><span><span class="usage-disk sys none"><span id="strength-bar" style="width:0"></span><span></span></span><span id="strength-text"></span></span>
|
||||
|
||||
:user_password_help:
|
||||
|
||||
_(Retype password)_:
|
||||
<input type="hidden" name="userPasswordConf" value="">
|
||||
: <input type="password" name="userPasswordConfGUI" maxlength="129" autocomplete="new-password" onKeyUp="this.form.cmdUserEdit.disabled=(this.form.userPasswordGUI.value != this.form.userPasswordConfGUI.value);">
|
||||
|
||||
|
||||
: <input type="submit" name="cmdUserEdit" value="_(Change)_" onclick="this.value='Change'" disabled><input type="button" value="_(Done)_" onclick="done('UserEdit')">
|
||||
</form>
|
||||
|
||||
<?if ($name == 'root'):?>
|
||||
<form markdown="1" method="POST" action="/update.php" onsubmit="return checkKey(this)" target="progressFrame">
|
||||
<input type="hidden" name="#include" value="/webGui/include/update.file.php">
|
||||
<input type="hidden" name="#file" value="<?=$file;?>">
|
||||
_(SSH authorized keys)_:
|
||||
: <textarea spellcheck="false" cols="80" rows="<?=max(substr_count($text,"\n")+1,10)?>" maxlength="16384" name="text" style="resize:none;white-space:normal;font-family:bitstream;width:65.5%"><?=htmlspecialchars($text)?></textarea>
|
||||
|
||||
|
||||
: <input type="submit" value="_(Save)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
|
||||
</form>
|
||||
<?endif;?>
|
||||
|
||||
<?if ($name != 'root' && $var['shareSMBEnabled'] != 'no'):?>
|
||||
<script>
|
||||
var users = {};
|
||||
var security = {};
|
||||
var readList = {};
|
||||
var writeList = {};
|
||||
<?
|
||||
$rw = 'read-write';
|
||||
$ro = 'read-only';
|
||||
$no = 'no-access';
|
||||
foreach ($users as $user) {
|
||||
$idx = $user['idx'];
|
||||
if ($idx) echo "users[\"{$user['name']}\"]='$idx';\n";
|
||||
}
|
||||
foreach ($shares as $share => $data) {
|
||||
echo "security[\"$share\"]=\"{$sec[$share]['security']}\";\n";
|
||||
echo "readList[\"$share\"]=\"{$sec[$share]['readList']}\";\n";
|
||||
echo "writeList[\"$share\"]=\"{$sec[$share]['writeList']}\";\n";
|
||||
}
|
||||
?>
|
||||
function updateAccess(form,data,n,i) {
|
||||
var name = "<?=$name?>";
|
||||
if (data) {
|
||||
if (n<i) {
|
||||
$.post('/update.htm',data[n], function(){setTimeout(function(){updateAccess(form,data,++n,i);},3000);});
|
||||
} else {
|
||||
$('div.spinner.fixed').hide();
|
||||
$('input[value="Reset"]').val('Done').prop('disabled',false).prop('onclick',null).off('click').click(function(){done('UserEdit');});
|
||||
}
|
||||
} else {
|
||||
var data = [], i = 0;
|
||||
$(form).find('select').each(function(){
|
||||
if ($(this).prop('id')) {
|
||||
var share = decodeURI($(this).prop('id'));
|
||||
var read = readList[share].split(',');
|
||||
var write = writeList[share].split(',');
|
||||
var access = '';
|
||||
data[i] = {};
|
||||
data[i]['shareName'] = share;
|
||||
data[i]['userAccess.0'] = '<?=$no?>';
|
||||
for (var user in users) {
|
||||
var idx = users[user];
|
||||
switch (security[share]) {
|
||||
case 'public':
|
||||
access = '<?=$rw?>';
|
||||
break;
|
||||
case 'secure':
|
||||
if (user == name) access = $(this).val();
|
||||
else access = write.includes(user) ? '<?=$rw?>' : '<?=$ro?>';
|
||||
break;
|
||||
case 'private':
|
||||
if (user == name) access = $(this).val();
|
||||
else access = write.includes(user) ? '<?=$rw?>' : (read.includes(user) ? '<?=$ro?>' : '<?=$no?>');
|
||||
break;
|
||||
}
|
||||
data[i]['userAccess.'+idx] = access;
|
||||
}
|
||||
data[i]['changeShareAccess'] = 'Apply';
|
||||
i++;
|
||||
}
|
||||
});
|
||||
$(form).find('input').prop('disabled',true);
|
||||
$('div.spinner.fixed').show();
|
||||
updateAccess(form,data,0,i);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<form markdown="1" method="POST">
|
||||
<?
|
||||
echo "<table class='share_status' style='margin-top:20px'>";
|
||||
echo "<thead><tr><td>"._('Share')."</td><td>"._('Security')."</td><td>"._('User Access')."</td></tr></thead>";
|
||||
echo "<tbody>";
|
||||
foreach ($shares as $share => $data) {
|
||||
if ($sec[$share]['export']=='-') continue;
|
||||
$security = $sec[$share]['security'];
|
||||
$read = in_array($name,explode(',',$sec[$share]['readList']));
|
||||
$write = in_array($name,explode(',',$sec[$share]['writeList']));
|
||||
switch ($security) {
|
||||
case 'public' : $access = $rw; break;
|
||||
case 'secure' : $access = $write ? $rw : $ro; break;
|
||||
case 'private': $access = $write ? $rw : ($read ? $ro : $no); break;}
|
||||
echo "<tr><td>$share</td><td>"._(ucfirst($security))."</td><td><select onchange='$(this).prop(\"id\",\"".rawurlencode($share)."\")'>";
|
||||
echo mk_option($access,$rw,_('Read/Write'));
|
||||
if ($security!='public') echo mk_option($access,$ro,_('Read-only'));
|
||||
if ($security=='private') echo mk_option($access,$no,_('No Access'));
|
||||
echo "</select></td></tr>";
|
||||
}
|
||||
echo "</tbody>";
|
||||
echo "</table>";
|
||||
?>
|
||||
|
||||
|
||||
: <input type="button" value="_(Apply)_" onclick="updateAccess(this.form)" disabled><input type="button" value="_(Done)_" onclick="done('UserEdit')">
|
||||
</form>
|
||||
<?endif;?>
|
||||
@@ -0,0 +1,47 @@
|
||||
Menu="Users"
|
||||
Title="Users"
|
||||
Tag="users"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$submenu = !empty($display['users']) && substr($display['users'],0,5)!='Tasks';
|
||||
if ($submenu) $path = './Users';
|
||||
ksort($users);
|
||||
?>
|
||||
<style>
|
||||
a.info span{top:66px;left:42px}
|
||||
<?if ($themes1):?>
|
||||
div#title{margin-top:-30px!important}
|
||||
<?endif;?>
|
||||
</style>
|
||||
|
||||
<div id="title" class="title"><span class="left"><i class="fa fa-bell title"></i>_(Management Access)_</span></div>
|
||||
<?$img = "/boot/config/plugins/dynamix/users/root.png"?>
|
||||
<div class="user-list" style="text-align:center"><a class="<?=(!empty($users['root']['desc']) ? 'info' : '')?>" href="<?=$path?>/UserEdit?name=root"><img src="<?=(file_exists($img) ? autov($img) : '/webGui/images/user.png')?>" class="picture" border="0" width="48" height="48"><br>root<span><?=htmlspecialchars($users['root']['desc'])?></span></a></div>
|
||||
|
||||
<div class="title"><span class="left"><i class="fa fa-cloud title"></i>_(Shares Access)_</span></div>
|
||||
<?foreach ($users as $user):?>
|
||||
<?if ($user['name'] == 'root') continue;?>
|
||||
<?$img = "/boot/config/plugins/dynamix/users/{$user['name']}.png"?>
|
||||
<div class="user-list" style="text-align:center"><a class="<?=(!empty($user['desc']) ? 'info' : '')?>" href="<?=$path?>/UserEdit?name=<?=htmlspecialchars(urlencode($user['name']))?>"><img src="<?=(file_exists($img) ? autov($img) : '/webGui/images/user.png')?>" class="picture" border="0" width="48" height="48"><br><?=htmlspecialchars($user['name'])?><span><?=htmlspecialchars($user['desc'])?></span></a></div>
|
||||
<?endforeach;?>
|
||||
|
||||
<?if (count($users)==1):?>
|
||||
_(No users are defined)_. _(Click **Add User** to create a user for remote shares access)_
|
||||
<?endif;?>
|
||||
|
||||
<div style='clear:both'></div>
|
||||
<form method="POST" action="<?=$path?>/UserAdd">
|
||||
<input type="submit" value="_(Add User)_"><?if ($submenu):?><input type="button" value="_(Done)_" onclick="done()"><?endif;?>
|
||||
</form>
|
||||
@@ -0,0 +1,4 @@
|
||||
Menu="Settings:3"
|
||||
Type="menu"
|
||||
Title="User Preferences"
|
||||
Tag="star"
|
||||
@@ -0,0 +1,5 @@
|
||||
Menu="$display['users'] Tasks:3"
|
||||
Type="xmenu"
|
||||
Title="Users"
|
||||
Icon="icon-users"
|
||||
Code="e945"
|
||||
@@ -0,0 +1,4 @@
|
||||
Menu="Settings"
|
||||
Title="User Utilities"
|
||||
Type="menu"
|
||||
Tag="cogs"
|
||||
@@ -0,0 +1,5 @@
|
||||
Menu="NetworkServices"
|
||||
Type="xmenu"
|
||||
Title="VPN Manager"
|
||||
Icon="icon-vpn"
|
||||
Tabs="false"
|
||||
@@ -0,0 +1,36 @@
|
||||
Menu="WebGui"
|
||||
Title="Vars"
|
||||
Icon="icon-vars"
|
||||
Tag="code"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?if (_var($display,'resize')):?>
|
||||
<script>
|
||||
function resize() {
|
||||
$('pre.up').height(Math.max(window.innerHeight-320,330));
|
||||
}
|
||||
$(function() {
|
||||
resize();
|
||||
$(window).bind('resize',function(){resize();});
|
||||
});
|
||||
</script>
|
||||
<?endif;?>
|
||||
<?
|
||||
$myPage['text'] = $page['text'] = $pages['Vars']['text'] = $language = $text = $notes = $site = '...';
|
||||
$globals = $GLOBALS;
|
||||
ksort($globals);
|
||||
if (isset($globals['_SERVER']['PHP_AUTH_PW'])) $globals['_SERVER']['PHP_AUTH_PW'] = "***";
|
||||
echo "<pre class='up'>",htmlspecialchars(print_r($globals,true)),"</pre>";
|
||||
?>
|
||||
<input type="button" value="_(Done)_" onclick="done()">
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,466 @@
|
||||
Menu="parentname:nnn"
|
||||
Title="Tunnel wgX"
|
||||
Tag="icon-vpn"
|
||||
---
|
||||
<?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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$check_wgX = in_array('wgX',$active) ? 'true' : 'false';
|
||||
$start_wgX = in_array('wgX',$autostart);
|
||||
$peer_wgX = $wgX = [];
|
||||
|
||||
$netpool['wgX'] = long2ip(ip2long($netpool['wg0'])+XXX*256);
|
||||
$netpool6['wgX'] = str_replace(':0:0:',':XXX:0:',$netpool6['wg0']);
|
||||
$netport['wgX'] = $netport['wg0']+XXX;
|
||||
|
||||
// read current configuration
|
||||
[$conf_wgX,$cfg_wgX,$this_wgX,$vpn_wgX] = readConf($peer_wgX,$wgX,'wgX');
|
||||
?>
|
||||
<script>
|
||||
netbase['wgX'] = <?=_var($netbase,'wgX')?>;
|
||||
netpool['wgX'] = "<?=_var($netpool,'wgX')?>";
|
||||
netport['wgX'] = "<?=_var($netport,'wgX')?>";
|
||||
netbase6['wgX'] = "<?=_var($netbase6,'wgX')?>";
|
||||
netpool6['wgX'] = "<?=_var($netpool6,'wgX')?>";
|
||||
tstate['wgX'] = "<?=$check_wgX ? 'active' : 'passive'?>";
|
||||
|
||||
$(function(){
|
||||
var ctrl = "<span class='status vhshift hshift'><i id='block-wgX' class='fa fa-fw fa-chevron-up' style='cursor:pointer' onclick='blockToggle("wgX")'></i></span>";
|
||||
ctrl += "<span class='even wide'><span class='status vshift label'>_(Autostart)_</span><span class='status vhshift'><input type='checkbox' id='start-wgX' style='display:none'<?=$start_wgX?' checked':''?>></span></span>";
|
||||
ctrl += "<span class='even'><span class='status vhshift'><input type='checkbox' id='view-wgX' style='display:none'></span></span>";
|
||||
ctrl += "<span class='even'><span class='status vhshift'><input type='checkbox' id='toggle-wgX' style='display:none'></span></span>";
|
||||
var form = $(document.wgX);
|
||||
getPublicIP($('#endpoint-wgX').val(),'wgX',$('#protocol-wgX').val());
|
||||
$('div.title').each(function(){if ($(this).html().indexOf('status vhshift')==-1) {$(this).find('span.left').append(ctrl);return false;}});
|
||||
$('#start-wgX').switchButton({labels_placement:'left',off_label:"_(Off)_",on_label:"_(On)_"});
|
||||
$('#start-wgX').change(function(){
|
||||
var start = $('#start-wgX').is(':checked') ? 'on' : 'off';
|
||||
$.post('/webGui/include/update.wireguard.php',{'#cmd':'autostart','#start':start,'#vtun':'wgX'});
|
||||
});
|
||||
$('#toggle-wgX').switchButton({labels_placement:'left',off_label:"_(Inactive)_",on_label:"_(Active)_",checked:<?=$check_wgX?>});
|
||||
$('#toggle-wgX').change(function(e){
|
||||
<?if ($this_wgX):?>
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var wg = $('#toggle-wgX').is(':checked') ? 'start' : 'stop';
|
||||
var type = 0;
|
||||
$('div[id^="index-wgX-"]').each(function(){
|
||||
var temp = $(this).find('select[name^="TYPE:"]').val();
|
||||
if (temp >= 7 && type==0) type = temp;
|
||||
});
|
||||
$.post('/webGui/include/update.wireguard.php',{'#cmd':'toggle','#wg':wg,'#vtun':'wgX','#type':type},function(ok){
|
||||
if (wg=='start') {
|
||||
if (ok==0) tstate['wgX']='active'; else $('#toggle-wgX').switchButton({checked:false});
|
||||
} else {
|
||||
if (ok==0) tstate['wgX']=''; else $('#toggle-wgX').switchButton({checked:true});
|
||||
}
|
||||
<?if (empty($wgX['UPNP:0'])):?>
|
||||
$.post('/webGui/include/update.wireguard.php',{'#cmd':'upnpc','#xml':xml,'#vtun':'wgX','#link':'<?=$link?>','#ip':'<?=$server?>','#wg':tstate['wgX']},function(data){$('span.upnp.wgX').text(data);});
|
||||
<?endif;?>
|
||||
});
|
||||
<?else:?>
|
||||
$('#toggle-wgX').prop('checked',false).trigger('change');
|
||||
<?endif;?>
|
||||
});
|
||||
if ($.cookie('view-wgX')=='advanced') {
|
||||
$('.advanced.wgX').show();
|
||||
form.find('i.fa-chevron-down').removeClass('fa-chevron-down').addClass('fa-chevron-up');
|
||||
form.find('input[class*="zone"]').show();
|
||||
form.find('i[class*="zone"]').each(function(i){if (!form.find('input[name="PublicKey:'+i+'"]').val()) {
|
||||
$('div.wgX.key'+i).show();
|
||||
$(this).removeClass('key-off').addClass('key-off');
|
||||
}});
|
||||
}
|
||||
$('#view-wgX').switchButton({labels_placement:'left',off_label:"_(Basic)_",on_label:"_(Advanced)_",checked:$.cookie('view-wgX')=='advanced'});
|
||||
$('#view-wgX').change(function(){
|
||||
if ($.cookie('view-wgX')==null) {
|
||||
// advanced view
|
||||
$.cookie('view-wgX','advanced',{expires:3650});
|
||||
$('.advanced.wgX').show('slow');
|
||||
form.find('input[class*="zone"]').show('slow');
|
||||
form.find('i.fa-chevron-down').removeClass('fa-chevron-down').addClass('fa-chevron-up');
|
||||
form.find('i[class*="zone"]').each(function(i){if (!form.find('input[name="PublicKey:'+i+'"]').val()) {
|
||||
$('div.wgX.key'+i).show('slow');
|
||||
$(this).removeClass('key-off').addClass('key-off');
|
||||
}});
|
||||
} else {
|
||||
// basic view
|
||||
$.removeCookie('view-wgX');
|
||||
$('.advanced.wgX').hide('slow');
|
||||
form.find('i.fa-chevron-up').removeClass('fa-chevron-up').addClass('fa-chevron-down');
|
||||
form.find('i[class*="zone"]').each(function(i){if (form.find('input[name="PublicKey:'+i+'"]').val()) {
|
||||
form.find('input[class$="zone'+i+'"]').hide('slow');
|
||||
$('div.wgX.key'+i).hide('slow');
|
||||
$(this).removeClass('key-off');
|
||||
}});
|
||||
}
|
||||
});
|
||||
showRemark(form);
|
||||
setProtocol(form,'wgX');
|
||||
form.find('input[name^="Address:"]').each(function(){
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
if (i > 0) $(this).on('input change',function(){form.find('#ping-button1-'+i).prop('disabled',$(this).val()=='');});
|
||||
});
|
||||
form.find('input[name^="Address6:"]').each(function(){
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
if (i > 0) $(this).on('input change',function(){form.find('.ping-button6-'+i).prop('disabled',$(this).val()=='');});
|
||||
});
|
||||
form.find('input[name^="gui:Endpoint:"]').each(function(){
|
||||
var i = $(this).attr('name').split(':')[2];
|
||||
$(this).on('input change',function(){
|
||||
form.find('#ping-button2-'+i).prop('disabled',$(this).val()=='');
|
||||
});
|
||||
});
|
||||
if (!$.cookie('block-wgX')) $('div#block-wgX').show(); else $('i#block-wgX').removeClass('fa-chevron-up').addClass('fa-chevron-down');
|
||||
if (xml) {
|
||||
$('div.upnp.wgX').show();
|
||||
<?if (empty($wgX['UPNP:0'])):?>
|
||||
$.post('/webGui/include/update.wireguard.php',{'#cmd':'upnpc','#xml':xml,'#vtun':'wgX','#link':'<?=$link?>','#ip':'<?=$server?>','#wg':$.cookie('my-wgX')||''},function(data){$('span.upnp.wgX').text(data);});
|
||||
<?endif;?>
|
||||
} else {
|
||||
form.find('select[name="UPNP:0"]').val('no');
|
||||
}
|
||||
var vpn = 0, lan = false
|
||||
form.find('select[name^="TYPE:"]').each(function(){
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
if ($(this).val()>=7 && vpn==0) vpn = $(this).val();
|
||||
lan |= $(this).val()=='6' || $(this).val() % 2;
|
||||
form.find('input[name="DNS:'+i+'"]').attr('placeholder',$(this).val()>=7 ? "(_(not used)_)" : "(_(optional)_)");
|
||||
showAccess(form,i,$(this).val());
|
||||
});
|
||||
if (vpn > 0) {
|
||||
form.find('select[name="NAT:0"]').val('no').prop('disabled',true);
|
||||
form.find('#addpeer-wgX').prop('disabled',true);
|
||||
}
|
||||
else if (form.find('select[name="NAT:0"]').val()=='no' && lan) $('span#my-static1-wgX').show();
|
||||
else if (lan) $('span#my-static2-wgX').show();
|
||||
});
|
||||
</script>
|
||||
<div markdown="1" id="block-wgX" style="display:none">
|
||||
<form markdown="1" name="wgX" autocomplete="off" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareSettings($(this),'wgX')">
|
||||
<input type="hidden" name="#include" value="/webGui/include/update.wireguard.php">
|
||||
<input type="hidden" name="#file" value="<?=$conf_wgX?>">
|
||||
<input type="hidden" name="#cfg" value="<?=$cfg_wgX?>">
|
||||
<input type="hidden" name="#cmd" value="update">
|
||||
<input type="hidden" name="#name" value="<?=$tower?>">
|
||||
<input type="hidden" name="#vtun" value="wgX">
|
||||
<input type="hidden" name="#type" value="0">
|
||||
<input type="hidden" name="#wg" value="">
|
||||
<input type="hidden" name="#internet" value="<?=$public?>">
|
||||
<input type="hidden" name="#subnets1" value="">
|
||||
<input type="hidden" name="#subnets2" value="">
|
||||
<input type="hidden" name="#shared1" value="">
|
||||
<input type="hidden" name="#shared2" value="">
|
||||
<input type="hidden" name="#deleted" value="">
|
||||
<input type="hidden" name="#locale" value="<?=$locale?>">
|
||||
_(Local name)_:
|
||||
: <span class="input"><input type="text" name="Name:0" class="wide" maxlength="99" value="<?=_var($wgX,"Name:0")?>" pattern="<?=$validname?>" title="_(Use only letters A-Z, digits or space,dash,underscore)_" placeholder="(_(optional)_)"></span>
|
||||
<span class="pin"><i class="fa fa-fw fa-eye eye0<?=$this_wgX?'':' key-off'?>" style="cursor:pointer" onclick="WGconfig(this,'wgX','')" title="_(View Local Config)_"></i>
|
||||
<i class="fa fa-fw fa-key zone0<?=isset($wgX['PublicKey:0'])?'':' key-off'?>" style="cursor:pointer" onclick="openClose($(document.wgX),null,'div.key0')" title="_(Toggle keys)_"></i>
|
||||
<i id="chevron-wgX-0" class="fa fa-fw fa-chevron-down" style="cursor:pointer" onclick="openClose($(document.wgX),this,'div.zone0')" title="_(Toggle view)_"></i></span>
|
||||
|
||||
:wg_local_name_help:
|
||||
|
||||
<div markdown="1" class="keys wgX key0"<?=isset($wgX['PublicKey:0'])?' style="display:none">':'>'?>
|
||||
_(Local private key)_:
|
||||
: <span class="input"><input type="text" name="PrivateKey:0" class="wide private-0" maxlength="64" value="<?=_var($wgX,'PrivateKey:0')?>" onchange="highlight($(document.wgX),this,0)" placeholder="(_(mandatory)_)" required></span>
|
||||
<input type="button" class="form" value="_(Generate Keypair)_" onclick="keypair($(document.wgX),'0')">
|
||||
|
||||
:wg_generate_keypair_help:
|
||||
|
||||
_(Local public key)_:
|
||||
: <span class="input"><input type="text" name="PublicKey:0" class="wide public-0" maxlength="64" value="<?=_var($wgX,'PublicKey:0')?>" onchange="highlight($(document.wgX),this,0)" placeholder="(_(mandatory)_)" required></span>
|
||||
|
||||
:wg_generate_keypair_help:
|
||||
|
||||
</div>
|
||||
<div markdown="1" class="advanced wgX zone0" style="display:none">
|
||||
_(Network protocol)_:
|
||||
: <span class="input"><select id="protocol-wgX" name="PROT:0" class="subnet" onchange="setProtocol($(document.wgX),'wgX',true)">
|
||||
<?=mk_option(_var($wgX,'PROT:0'), "", _("IPv4 only"))?>
|
||||
<?=mk_option(_var($wgX,'PROT:0'), "6", _("IPv6 only"))?>
|
||||
<?=mk_option(_var($wgX,'PROT:0'), "46", _("IPv4 + IPv6"))?>
|
||||
</select></span>
|
||||
|
||||
<div markdown="1" class="ipv4 wgX" style="display:none">
|
||||
_(Local tunnel network pool)_:
|
||||
<input type="hidden" name="Network:0" value="">
|
||||
: <span class="input"><input type="text" name="gui:Network:0" class="subnet" maxlength="15" value="<?=explode('/',_var($wgX,'Network:0'))[0]?>" onchange="setPool($(document.wgX),'wgX')" pattern="<?=$validIP4?>" title="_(IPv4 network)_" placeholder="<?=_var($netpool,'wgX')?>">/
|
||||
<input type="number" name="gui:Mask:0" class="mask" min="1" max="32" value="<?=my_explode('/',_var($wgX,'Network:0'))[1]?>" onchange="if(quickValidate(this)) {setPool($(document.wgX),'wgX')}" placeholder="24"></span>
|
||||
|
||||
</div>
|
||||
<div markdown="1" class="ipv6 wgX" style="display:none">
|
||||
_(Local tunnel network pool IPv6)_:
|
||||
<input type="hidden" name="Network6:0" value="">
|
||||
: <span class="input"><input type="text" name="gui:Network6:0" class="subnet" maxlength="40" value="<?=explode('/',_var($wgX,'Network6:0'))[0]?>" onchange="setPool6($(document.wgX),'wgX')" pattern="<?=$validIP6?>" title="_(IPv6 network)_" placeholder="<?=_var($netpool6,'wgX')?>">/
|
||||
<input type="number" name="gui:Mask6:0" class="mask" min="1" max="128" value="<?=my_explode('/',_var($wgX,'Network6:0'))[1]?>" onchange="if(quickValidate(this)) {setPool6($(document.wgX),'wgX')}" placeholder="64"></span>
|
||||
|
||||
</div>
|
||||
:wg_local_tunnel_network_pool_X_help:
|
||||
|
||||
<div markdown="1" class="ipv4 wgX" style="display:none">
|
||||
_(Local tunnel address)_:
|
||||
: <span class="input"><input type="text" name="Address:0" class="subnet" maxlength="15" value="<?=_var($wgX,'Address:0')?:long2ip(_var($netbase,'wgX')+1)?>" onchange="verifyInSubnet(this);" pattern="<?=$validIP4?>" title="_(IPv4 address)_"></span>
|
||||
|
||||
:wg_local_tunnel_address_help:
|
||||
|
||||
</div>
|
||||
<div markdown="1" class="ipv6 wgX" style="display:none">
|
||||
_(Local tunnel address IPv6)_:
|
||||
: <span class="input"><input type="text" name="Address6:0" class="subnet" maxlength="40" value="<?=_var($wgX,'Address6:0')?:(_var($netbase6,'wgX').'1')?>" onchange="verifyInSubnet6(this);" pattern="<?=$validIP6?>" title="_(IPv6 address)_"></span>
|
||||
|
||||
:wg_local_tunnel_address_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
_(Local endpoint)_:
|
||||
: <span class="input"><input type="text" id="endpoint-wgX" name="Endpoint:0" class="subnet" value="<?=$vpn_wgX?'':_var($wgX,'Endpoint:0')?>" onchange="toLC(this);quickValidate(this);" pattern="<?=$validText?>" title="_(IP address or FQDN)_" placeholder="<?=$vpn_wgX?'(_(not used)_)':preg_replace('/^(www\.).+(\.unraid.net)$/','$1<hash>$2',$public)?>">:
|
||||
<input type="number" name="gui:ListenPort:0" class="port" min="1" max="65535" value="<?=$vpn_wgX?'':_var($wgX,'ListenPort:0')?>" onchange="if(quickValidate(this)) {portRemark($(document.wgX),'wgX',this.value)}" placeholder="<?=$vpn_wgX?'':_var($netport,'wgX')?>"></span>
|
||||
<span class="remark block" style="display:none">_(Remark)_: _(configure your router with port forwarding of port)_ **<span id="my-port-wgX"><?=_var($wgX,'ListenPort:0')?:_var($netport,'wgX')?></span>/_(UDP)_** _(to)_ **<?=$server?>:<?=_var($wgX,'ListenPort:0')?:_var($netport,'wgX')?>**</span><span class="upnp wgX block"></span>
|
||||
<input type="hidden" name="ListenPort:0" value=""><dl id="endpoint4-wgX" style="display:none"></dl><dl id="endpoint6-wgX" style="display:none"></dl>
|
||||
|
||||
:wg_local_endpoint_X_help:
|
||||
|
||||
<div markdown="1" class="advanced wgX zone0" style="display:none">
|
||||
_(Local server uses NAT)_:
|
||||
: <span class="input"><select name="NAT:0" class="narrow" onchange="showRoute($(document.wgX),'wgX',0)">
|
||||
<?=mk_option(_var($wgX,'NAT:0'), "", _("Yes"))?>
|
||||
<?=mk_option(_var($wgX,'NAT:0'), "no", _("No"))?>
|
||||
</select></span>
|
||||
<span id="my-static1-wgX" class="block" style="display:none">_(Remark)_: _(configure your router with a static route of)_ **<?=_var($wgX,'Network:0')?>** _(to)_ **<?=$server?>**</span><span id="my-static2-wgX" class="block" style="display:none">_(Remark)_: _(docker containers on custom networks need static routing)_ **<?=_var($wgX,'Network:0')?>** _(to)_ **<?=$server?>**</span>
|
||||
|
||||
:wg_local_server_uses_nat_help:
|
||||
|
||||
<div markdown="1" class="upnp wg0" style="display:none">
|
||||
_(Local gateway uses UPnP)_:
|
||||
: <span class="input"><select name="UPNP:0" class="narrow" onchange="showRemark($(document.wgX))">
|
||||
<?=mk_option(_var($wgX,'UPNP:0'), "", _("Yes"))?>
|
||||
<?=mk_option(_var($wgX,'UPNP:0'), "no", _("No"))?>
|
||||
</select></span>
|
||||
|
||||
:wg_local_gateway_uses_upnp_help:
|
||||
|
||||
</div>
|
||||
_(Local tunnel firewall)_:
|
||||
: <span class="input"><input type="text" name="DROP:0" class="wide" value="<?=_var($wgX,'DROP:0')?>" onchange="quickValidate(this);" pattern="<?=$validList?>" title="_(Comma separated list of IPv4 and IPv6 IP addresses)_, _(CIDR optional)_" placeholder="(_(optional)_)"></span>
|
||||
_(Rule)_: <select name="RULE:0" class="auto">
|
||||
<?=mk_option(_var($wgX,'RULE:0'), "", _("Deny"))?>
|
||||
<?=mk_option(_var($wgX,'RULE:0'), "1", _("Allow"))?>
|
||||
</select>
|
||||
|
||||
:wg_local_tunnel_firewall_help:
|
||||
|
||||
_(MTU size)_:
|
||||
: <span class="input"><input type="number" name="MTU:0" class="trim" min="68" max="9198" value="<?=_var($wgX,'MTU:0')?>" onchange="quickValidate(this);" placeholder="(_(automatic)_)">_(bytes)_</span>
|
||||
|
||||
:wg_mtu_size_help:
|
||||
|
||||
<!--
|
||||
_(DNS servers)_:
|
||||
: <span class="input"><input type="text" name="DNS:0" class="wide" value="" placeholder="(_(optional)_)"></span>
|
||||
|
||||
> Not used at the moment. It gives errors when used together with Unraid.
|
||||
-->
|
||||
</div>
|
||||
<input type="hidden" name="PostUp:0:0" value="<?=$postUp0?>">
|
||||
<input type="hidden" name="PostUp:0:1" value="<?=$postUp1?>">
|
||||
<input type="hidden" name="PostUp:0:2" value="">
|
||||
<input type="hidden" name="PostDown:0:0" value="<?=$postDown0?>">
|
||||
<input type="hidden" name="PostDown:0:1" value="<?=$postDown1?>">
|
||||
<input type="hidden" name="PostDown:0:2" value="">
|
||||
|
||||
:wg_peer_configuration_help:
|
||||
|
||||
<div id="peers-list-wgX" style="display:none"></div>
|
||||
<?foreach ($peer_wgX as $i):?>
|
||||
<div markdown="1" id="index-wgX-<?=$i?>" class="shade-<?=$display['theme']?>">
|
||||
_(Peer name)_:
|
||||
: <span class="input"><input type="text" name="Name:<?=$i?>" class="wide" maxlength="99" value="<?=_var($wgX,"Name:$i")?>" onchange="quickValidate(this);" pattern="<?=$validname?>" title="_(Use only letters A-Z, digits or space,dash,underscore)_" placeholder="(_(optional)_)"></span>
|
||||
<input type="button" class="form" value="_(Delete Peer)_" onclick="delPeer($(document.wgX),'#index-wgX-<?=$i?>')">
|
||||
<span class="pin"><i class="fa fa-fw fa-eye eye<?=$i?><?=(file_exists("$etc/peers/peer-$tower-wgX-$i.conf")&&isset($wgX["TYPE:$i"])&&$wgX["TYPE:$i"]<=6)?'':' key-off'?>" style="cursor:pointer" onclick="WGconfig(this,'peer-<?=$tower?>-wgX-<?=$i?>','/peers')" title="_(View Peer Config)_"></i>
|
||||
<i class="fa fa-fw fa-key zone<?=$i?><?=isset($wgX["PublicKey:$i"])?'':' key-off'?>" style="cursor:pointer" onclick="openClose($(document.wgX),null,'div.key<?=$i?>')" title="_(Toggle keys)_"></i>
|
||||
<i id="chevron-wgX-<?=$i?>" class="fa fa-fw fa-chevron-down" style="cursor:pointer" onclick="openClose($(document.wgX),this,'div.zone<?=$i?>')" title="_(Toggle view)_"></i></span>
|
||||
|
||||
:wg_peer_name_help:
|
||||
|
||||
_(Peer type of access)_:
|
||||
: <span class="input"><select name="TYPE:<?=$i?>" class="auto" onchange="updatePeer($(document.wgX),<?=$i?>,this.value,'wgX')">
|
||||
<?=mk_option(_var($wgX,"TYPE:$i"), "0", _("Remote access to server"))?>
|
||||
<?=mk_option(_var($wgX,"TYPE:$i"), "1", _("Remote access to LAN"))?>
|
||||
<?=mk_option(_var($wgX,"TYPE:$i"), "2", _("Server to server access"))?>
|
||||
<?=mk_option(_var($wgX,"TYPE:$i"), "3", _("LAN to LAN access"))?>
|
||||
<?=mk_option(_var($wgX,"TYPE:$i"), "4", _("Server hub & spoke access"))?>
|
||||
<?=mk_option(_var($wgX,"TYPE:$i"), "5", _("LAN hub & spoke access"))?>
|
||||
<?=mk_option(_var($wgX,"TYPE:$i"), "6", _("Remote tunneled access"))?>
|
||||
<?=mk_option(_var($wgX,"TYPE:$i"), "7", _("VPN tunneled access for system"),count($peer_wgX)==1?'':'disabled')?>
|
||||
<?=mk_option(_var($wgX,"TYPE:$i"), "8", _("VPN tunneled access for docker"))?>
|
||||
</select></span>
|
||||
<span id="access-type-<?=$i?>" class="access-type"></span>
|
||||
|
||||
<?if ($i==1):?>
|
||||
> ?>)
|
||||
<?endif;?>
|
||||
|
||||
<div markdown="1" class="keys wgX key<?=$i?>"<?=isset($wgX["PublicKey:$i"])?' style="display:none">':'>'?>
|
||||
_(Peer private key)_:
|
||||
: <span class="input"><input type="text" name="PrivateKey:<?=$i?>" class="wide private-<?=$i?>" maxlength="64" value="<?=_var($wgX,"PrivateKey:$i")?>" onchange="highlight($(document.wgX),this,<?=$i?>)" placeholder="(_(optional)_)"></span>
|
||||
<input type="button" class="form" value="_(Generate Keypair)_" onclick="keypair($(document.wgX),'<?=$i?>')">
|
||||
|
||||
:wg_generate_keypair_help:
|
||||
|
||||
_(Peer public key)_:
|
||||
: <span class="input"><input type="text" name="PublicKey:<?=$i?>" class="wide public-<?=$i?>" maxlength="64" value="<?=_var($wgX,"PublicKey:$i")?>" onchange="highlight($(document.wgX),this,<?=$i?>)" placeholder="(_(mandatory)_)" required></span>
|
||||
|
||||
:wg_generate_keypair_help:
|
||||
|
||||
_(Peer preshared key)_:
|
||||
: <span class="input"><input type="text" name="PresharedKey:<?=$i?>" class="wide preshared-<?=$i?>" maxlength="64" value="<?=_var($wgX,"PresharedKey:$i")?>" onchange="highlight($(document.wgX),this,<?=$i?>)" placeholder="(_(optional)_)"></span>
|
||||
<input type="button" class="form" value="_(Generate Key)_" onclick="presharedkey($(document.wgX),'<?=$i?>')">
|
||||
|
||||
:wg_peer_preshared_key_help:
|
||||
|
||||
</div>
|
||||
<div markdown="1" class="advanced wgX zone<?=$i?>" style="display:none">
|
||||
<div markdown="1" class="ipv4 wgX" style="display:none">
|
||||
_(Peer tunnel address)_:
|
||||
: <span class="input"><input type="text" name="Address:<?=$i?>" class="subnet" maxlength="15" value="<?=_var($wgX,"Address:$i")?>" onchange="if(verifyInSubnet(this)){setAllow($(document.wgX),this.value,<?=$i?>)}" pattern="<?=$validIP4?>" title="_(IPv4 address)_"></span>
|
||||
<input type="button" class="form ping-button1-<?=$i?>" value="_(Ping)_" onclick="ping($(document.wgX),this,'input[name="Address:<?=$i?>"]')"<?=isset($wgX["Address:$i"])?'':' disabled'?>>
|
||||
|
||||
</div>
|
||||
<div markdown="1" class="ipv6 wgX" style="display:none">
|
||||
_(Peer tunnel address IPv6)_:
|
||||
: <span class="input"><input type="text" name="Address6:<?=$i?>" class="subnet" maxlength="40" value="<?=_var($wgX,"Address6:$i")?>" onchange="if(verifyInSubnet6(this)){setAllow6($(document.wgX),this.value,<?=$i?>)}" pattern="<?=$validIP6?>" title="_(IPv6 address)_"></span>
|
||||
<input type="button" class="form ping-button6-<?=$i?>" value="_(Ping)_" onclick="ping($(document.wgX),this,'input[name="Address6:<?=$i?>"]')"<?=isset($wgX["Address6:$i"])?'':' disabled'?>>
|
||||
|
||||
</div>
|
||||
:wg_peer_tunnel_address_help:
|
||||
|
||||
_(Peer endpoint)_:
|
||||
<input type="hidden" name="Endpoint:<?=$i?>" value="">
|
||||
: <span class="input"><input type="text" name="gui:Endpoint:<?=$i?>" class="subnet" value="<?=_var($wgX,"Endpoint:$i")?>" pattern="<?=$validText?>" title="_(IP address or FQDN)_" onchange="toLC(this);quickValidate(this);" <?=($vpn_wgX||(int)_var($wgX,"TYPE:$i",0)==2||(int)_var($wgX,"TYPE:$i",0)==3)?'placeholder="(_(mandatory)_)" required':'placeholder="(_(not used)_)"'?>>:
|
||||
<input type="number" name="gui:ListenPort:<?=$i?>" class="port" min="1" max="65535" value="<?=_var($wgX,"ListenPort:$i")?>" onchange="quickValidate(this);"<?=isset($wgX["Endpoint:$i"])?" placeholder=\"".(_var($wgX,'ListenPort:0')?:_var($netport,'wgX'))."\"":""?>></span>
|
||||
<input type="button" class="form ping-button2-<?=$i?>" value="Ping" onclick="ping($(document.wgX),this,'input[name="gui:Endpoint:<?=$i?>"]')"<?=isset($wgX["Endpoint:$i"])?'':' disabled'?>>
|
||||
|
||||
:wg_peer_endpoint_help:
|
||||
|
||||
_(Peer allowed IPs)_:
|
||||
: <span class="input"><input type="text" name="AllowedIPs:<?=$i?>" class="wide" value="<?=_var($wgX,"AllowedIPs:$i")?>" onchange="quickValidate(this);" pattern="<?=$validList?>" title="_(Comma separated list of IPv4 and IPv6 IP addresses)_, _(CIDR optional)_" placeholder="(_(mandatory)_)" required></span>
|
||||
|
||||
:wg_peer_allowed_ips_help:
|
||||
|
||||
_(Peer DNS server)_:
|
||||
: <span class="input"><input type="text" name="DNS:<?=$i?>" class="subnet" maxlength="40" value="<?=_var($wgX,"DNS:$i")?>" onchange="quickValidate(this);" pattern="<?=$validDNSServerList?>" title="_(Comma separated list of IPv4 and IPv6 IP addresses)_"<?=(int)_var($wgX,"TYPE:$i",0)!=6?'placeholder="(_(optional)_)"':'placeholder="(_(mandatory)_)" required'?>></span>
|
||||
|
||||
:wg_peer_dns_server_help:
|
||||
|
||||
_(Persistent keepalive)_:
|
||||
: <span class="input"><input type="number" name="PersistentKeepalive:<?=$i?>" class="trim" min="0" max="600" value="<?=_var($wgX,"PersistentKeepalive:$i")?>" onchange="quickValidate(this);" placeholder="(_(disabled)_)">_(seconds)_</span>
|
||||
|
||||
:wg_persistent_keepalive_help:
|
||||
|
||||
</div>
|
||||
<span class="pin">_(Data received)_: <span class="rx-wgX-<?=$i?>">0 B</span>_(Data sent)_: <span class="tx-wgX-<?=$i?>">0 B</span><br>_(Last handshake)_: <span class="hs-wgX-<?=$i?>">_(unknown)_</span></span>
|
||||
</div>
|
||||
<?endforeach;?>
|
||||
|
||||
|
||||
: <input type="submit" value="_(Apply)_" onclick="return(validateForm($(document.wgX),'wgX'))" disabled><input type="button" value="_(Done)_" onclick="done()"><input type="button" id="addpeer-wgX" value="_(Add Peer)_" onclick="addPeer($(document.wgX),'wgX')"><input type="button" class="advanced wgX" value="_(Delete Tunnel)_" style="float:right;display:none" onclick="delTunnel('wgX')">
|
||||
</form>
|
||||
|
||||
<script markdown="1" type="text/html" id="peer-template-wgX">
|
||||
<div markdown="1" id="index-wgX-INDEX" class="shade-<?=$display['theme']?>">
|
||||
_(Peer name)_:
|
||||
: <span class="input"><input type="text" name="Name:INDEX" class="wide" maxlength="99" value="" onchange="quickValidate(this);" pattern="<?=$validname?>" title="_(Use only letters A-Z, digits or space,dash,underscore)_" placeholder="(_(optional)_)"></span>
|
||||
<span class="pin"><i class="fa fa-fw fa-eye eyeINDEX key-off" title="_(Show Peer Config)_"></i>
|
||||
<i class="fa fa-fw fa-key zoneINDEX key-off" title="_(Toggle keys)_"></i>
|
||||
<i id="chevron-wgX-INDEX" class="fa fa-fw fa-chevron-down" style="cursor:pointer" onclick="openClose($(document.wgX),this,'div.zoneINDEX')" title="_(Toggle view)_"></i></span>
|
||||
|
||||
:wg_peer_name_help:
|
||||
|
||||
_(Peer type of access)_:
|
||||
: <span class="input"><select name="TYPE:INDEX" class="auto" onchange="updatePeer($(document.wgX),INDEX,this.value,'wgX')">
|
||||
<?=mk_option(0, "0", _("Remote access to server"))?>
|
||||
<?=mk_option(0, "1", _("Remote access to LAN"))?>
|
||||
<?=mk_option(0, "2", _("Server to server access"))?>
|
||||
<?=mk_option(0, "3", _("LAN to LAN access"))?>
|
||||
<?=mk_option(0, "4", _("Server hub & spoke access"))?>
|
||||
<?=mk_option(0, "5", _("LAN hub & spoke access"))?>
|
||||
<?=mk_option(0, "6", _("Remote tunneled access"))?>
|
||||
<?=mk_option(0, "7", _("VPN tunneled access for system"),'disabled')?>
|
||||
<?=mk_option(0, "8", _("VPN tunneled access for docker"))?>
|
||||
</select></span>
|
||||
<span id="access-type-INDEX" class="access-type"></span>
|
||||
|
||||
> ?>)
|
||||
|
||||
<div markdown="1" class="keys wgX keyINDEX">
|
||||
_(Peer private key)_:
|
||||
: <span class="input"><input type="text" name="PrivateKey:INDEX" class="wide private-INDEX" maxlength="64" value="" onchange="highlight($(document.wgX),this,0)" placeholder="(_(optional)_)"></span>
|
||||
<input type="button" class="form" value="_(Generate Keypair)_" onclick="keypair($(document.wgX),'INDEX')">
|
||||
|
||||
:wg_generate_keypair_help:
|
||||
|
||||
_(Peer public key)_:
|
||||
: <span class="input"><input type="text" name="PublicKey:INDEX" class="wide public-INDEX" maxlength="64" onchange="highlight($(document.wgX),this,0)" placeholder="(_(mandatory)_)" value="" required></span>
|
||||
|
||||
:wg_generate_keypair_help:
|
||||
|
||||
_(Peer preshared key)_:
|
||||
: <span class="input"><input type="text" name="PresharedKey:INDEX" class="wide preshared-INDEX" maxlength="64" value="" onchange="highlight($(document.wgX),this,0)" placeholder="(_(optional)_)"></span>
|
||||
<input type="button" class="form" value="_(Generate Key)_" onclick="presharedkey($(document.wgX),'INDEX')">
|
||||
|
||||
:wg_peer_preshared_key_help:
|
||||
|
||||
</div>
|
||||
<div markdown="1" class="advanced wgX zoneINDEX" style="display:none">
|
||||
<div markdown="1" class="ipv4 wgX" style="display:none">
|
||||
_(Peer tunnel address)_:
|
||||
: <span class="input"><input type="text" name="Address:INDEX" class="subnet" maxlength="15" value="" onchange="if(verifyInSubnet(this)){setAllow($(document.wgX),this.value,INDEX)}" pattern="<?=$validIP4?>" title="_(IPv4 address)_"></span>
|
||||
<input type="button" class="form ping-button1-INDEX" value="_(Ping)_" onclick="ping($(document.wgX),this,'input[name="Address:INDEX"]')" disabled>
|
||||
|
||||
</div>
|
||||
<div markdown="1" class="ipv6 wgX" style="display:none">
|
||||
_(Peer tunnel address IPv6)_:
|
||||
: <span class="input"><input type="text" name="Address6:INDEX" class="subnet" maxlength="40" value="" onchange="if(verifyInSubnet6(this)){setAllow6($(document.wgX),this.value,INDEX)}" pattern="<?=$validIP6?>" title="_(IPv6 address)_"></span>
|
||||
<input type="button" class="form ping-button6-INDEX" value="_(Ping)_" onclick="ping($(document.wgX),this,'input[name="Address6:INDEX"]')" disabled>
|
||||
|
||||
</div>
|
||||
:wg_peer_tunnel_address_help:
|
||||
|
||||
_(Peer endpoint)_:
|
||||
<input type="hidden" name="Endpoint:INDEX" value="">
|
||||
: <span class="input"><input type="text" name="gui:Endpoint:INDEX" class="subnet" value="" pattern="<?=$validText?>" title="_(IP address or FQDN)_" onchange="toLC(this);quickValidate(this);" placeholder="(_(not used)_)">:
|
||||
<input type="number" name="gui:ListenPort:INDEX" class="port" min="1" max="65535" value="" onchange="quickValidate(this);"></span>
|
||||
<input type="button" class="form ping-button2-INDEX" value="_(Ping)_" onclick="ping($(document.wgX),this,'input[name="gui:Endpoint:INDEX"]')" disabled>
|
||||
|
||||
:wg_peer_endpoint_help:
|
||||
|
||||
_(Peer allowed IPs)_:
|
||||
: <span class="input"><input type="text" name="AllowedIPs:INDEX" class="wide" value="" onchange="quickValidate(this);" pattern="<?=$validList?>" title="_(Comma separated list of IPv4 and IPv6 IP addresses)_, _(CIDR optional)_" placeholder="(_(mandatory)_)" required></span>
|
||||
|
||||
:wg_peer_allowed_ips_help:
|
||||
|
||||
_(Peer DNS server)_:
|
||||
: <span class="input"><input type="text" name="DNS:INDEX" class="subnet" maxlength="40" value="" onchange="quickValidate(this);" pattern="<?=$validDNSServerList?>" title="_(Comma separated list of IPv4 and IPv6 IP addresses)_" placeholder="(_(optional)_)"></span>
|
||||
|
||||
:wg_peer_dns_server_help:
|
||||
|
||||
_(Persistent keepalive)_:
|
||||
: <span class="input"><input type="number" name="PersistentKeepalive:INDEX" class="trim" min="0" max="600" value="" onchange="quickValidate(this);" placeholder="(_(disabled)_)">_(seconds)_</span>
|
||||
|
||||
:wg_persistent_keepalive_help:
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
@@ -0,0 +1,4 @@
|
||||
Menu="Tools:20"
|
||||
Type="menu"
|
||||
Title="webGUI"
|
||||
Tag="tv"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user