mirror of
https://github.com/unraid/webgui.git
synced 2026-02-22 18:29:47 -06:00
Merge pull request #2215 from bergware/master
Encryption: fix passphrase encryption not working in some cases
This commit is contained in:
@@ -17,27 +17,36 @@ Nchan="device_list,disk_load,parity_list"
|
||||
?>
|
||||
<?
|
||||
$keyfile = file_exists(_var($var,'luksKeyfile'));
|
||||
$missing = file_exists('/var/tmp/missing.tmp');
|
||||
$spot = _var($var,'mdResyncPos',0)>0;
|
||||
$poolsOnly = (_var($var,'SYS_ARRAY_SLOTS') == 0 ) ? true : false;
|
||||
$poolsOnly = (_var($var,'SYS_ARRAY_SLOTS') == 0 ) ? true : false;
|
||||
|
||||
/* only one of $present, $missing, or $wrong will be true, or all will be false */
|
||||
$forced = $present = $wrong = false;
|
||||
foreach ($disks as $disk) {
|
||||
if (strpos(_var($disk,'fsType'),'luks:')!==false || (_var($disk,'fsType')=='auto' && strpos(_var($var,'defaultFsType'),'luks:')!==false)) $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;
|
||||
$forced = $present = $missing = $wrong = false;
|
||||
|
||||
foreach (luks_filter($disks) as $disk) {
|
||||
$fsType = _var($disk,'fsType');
|
||||
$luks = str_starts_with($fsType,'luks:');
|
||||
if ($luks || ($fsType == 'auto' && str_starts_with(_var($var,'defaultFsType'),'luks:'))) $forced = true;
|
||||
if ($luks) switch (_var($disk,'luksState',0)) {
|
||||
case 1: $present = true; break;
|
||||
case 2: $missing = true; break;
|
||||
case 3: $wrong = true; break;
|
||||
}
|
||||
}
|
||||
|
||||
$encrypt = $forced || $present || $missing || $wrong;
|
||||
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;
|
||||
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)'>";
|
||||
@@ -91,15 +100,15 @@ var recover = null;
|
||||
String.prototype.no_tilde = function(){return this.replace('<?=$_tilde_?>','<?=$_proxy_?>');}
|
||||
String.prototype.master = function(){return this.split('<?=$_tilde_?>')[0];}
|
||||
|
||||
function toggle_state(device,name,action) {
|
||||
function toggle_state(device, name, action) {
|
||||
var button = null;
|
||||
if (name) {
|
||||
var group = name.replace(/(\d+|\*)$/,'');
|
||||
if (name.slice(-1)!='*') {
|
||||
if (name.slice(-1) != '*') {
|
||||
// single device
|
||||
$('#dev-'+name.no_tilde()).removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
|
||||
} else {
|
||||
if (group=='disk') {
|
||||
if (group == 'disk') {
|
||||
// array devices
|
||||
$('[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');
|
||||
@@ -108,17 +117,17 @@ function toggle_state(device,name,action) {
|
||||
$('[id^="dev-'+group.master()+'"]').removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
|
||||
}
|
||||
}
|
||||
} else if (device!='Clear') {
|
||||
} else if (device != 'Clear') {
|
||||
// all devices
|
||||
$('[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},function(){setTimeout(function(){devices.start().monitor();},1000);if (button) $(button).prop('disabled',false);});
|
||||
$.post('/webGui/include/ToggleState.php', {device:device,name:name,action:action}, function(){setTimeout(function(){devices.start().monitor();},1000);if (button) $(button).prop('disabled',false);});
|
||||
}
|
||||
|
||||
function display_diskio() {
|
||||
if ($.cookie('diskio')===undefined) {
|
||||
if ($.cookie('diskio') === undefined) {
|
||||
$('span.diskio').show(); $('span.number').hide();
|
||||
} else {
|
||||
$('span.number').show(); $('span.diskio').hide();
|
||||
@@ -127,9 +136,9 @@ function display_diskio() {
|
||||
|
||||
function toggle_diskio(init) {
|
||||
if (!init) {
|
||||
if ($.cookie('diskio')===undefined) $.cookie('diskio','diskio',{expires:3650}); else $.removeCookie('diskio');
|
||||
if ($.cookie('diskio') === undefined) $.cookie('diskio','diskio',{expires:3650}); else $.removeCookie('diskio');
|
||||
}
|
||||
if ($.cookie('diskio')===undefined) {
|
||||
if ($.cookie('diskio') === undefined) {
|
||||
$('i.toggle').removeClass('fa-list').addClass('fa-tachometer');
|
||||
$('#clearstats').addClass('hidden');
|
||||
} else {
|
||||
@@ -148,7 +157,7 @@ function selectInput(form) {
|
||||
form.input.value = 'file';
|
||||
form.input.disabled = true;
|
||||
<?endif;?>
|
||||
if (form.input.value=='text') {
|
||||
if (form.input.value == 'text') {
|
||||
form.file.value = '';
|
||||
form.local.value = '';
|
||||
<?if ($forced):?>
|
||||
@@ -187,17 +196,17 @@ function selectInput(form) {
|
||||
}
|
||||
}
|
||||
|
||||
function getFileContent(event,form) {
|
||||
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,parityWarn) {
|
||||
function prepareInput(form, button, parityWarn) {
|
||||
button.disabled = true;
|
||||
$.post('/webGui/include/Report.php',{cmd:'state',pools:'<?=implode(',',$pools)?>'},function(state) {
|
||||
if (state.length==0) {
|
||||
if (state.length == 0) {
|
||||
$(form).append('<input type="hidden" name="cmdStart" value="Start">');
|
||||
if (form.input === undefined) {
|
||||
parityWarn ? parityWarning(form,button) : form.submit();
|
||||
@@ -219,7 +228,13 @@ function prepareInput(form,button,parityWarn) {
|
||||
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)_"});
|
||||
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;
|
||||
}
|
||||
@@ -229,12 +244,20 @@ function prepareInput(form,button,parityWarn) {
|
||||
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(){button.disabled=false;});
|
||||
swal({
|
||||
title:"_(Wrong Pool State)_",
|
||||
text:state,
|
||||
type:'error',
|
||||
html:true,
|
||||
confirmButtonText:"_(Ok)_"
|
||||
},function(){
|
||||
button.disabled=false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function parityWarning(form,button) {
|
||||
function parityWarning(form, button) {
|
||||
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)_";
|
||||
@@ -244,7 +267,15 @@ function parityWarning(form,button) {
|
||||
} 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(confirmed){
|
||||
swal({
|
||||
title:"_(Proceed to start)_",
|
||||
text:text,
|
||||
html:true,
|
||||
type:'warning',
|
||||
showCancelButton:true,
|
||||
confirmButtonText:"_(Proceed)_",
|
||||
cancelButtonText:"_(Cancel)_"
|
||||
},function(confirmed){
|
||||
confirmed ? form.submit() : button.disabled=false;
|
||||
});
|
||||
}
|
||||
@@ -257,16 +288,36 @@ function 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();});
|
||||
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) {
|
||||
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();});
|
||||
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;?>
|
||||
@@ -292,14 +343,24 @@ function parityHistory() {
|
||||
openChanges("parity_history", "_(Parity Operation History)_", "phistory");
|
||||
}
|
||||
|
||||
function shutdown_now(form,cmd) {
|
||||
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();});
|
||||
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;?>
|
||||
@@ -311,25 +372,25 @@ function toggleApply(checked) {
|
||||
|
||||
<?if ($tabbed):?>
|
||||
$('.tabs').append(ctrl);
|
||||
if ($.cookie('tab')=='tab0') $('i.toggle').hide();
|
||||
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") .right').each(function(){$(this).append(ctrl);});
|
||||
<?endif;?>
|
||||
$('.tooltip_diskio').tooltipster({delay:100,trigger:'custom',triggerOpen:{mouseenter:true},triggerClose:{click:false,scroll:true,mouseleave:true}});
|
||||
|
||||
<?if (_var($var,'fsState')=='Started'):?>
|
||||
<?if (_var($var,'fsState') == 'Started'):?>
|
||||
var mymonitor = new NchanSubscriber('/sub/mymonitor',{subscriber:'websocket', reconnectTimeout:5000});
|
||||
mymonitor.on('message', function(state) {
|
||||
switch (state) {
|
||||
case '0': // normal operation
|
||||
$('#stop-button').prop('disabled',false);
|
||||
$('#stop-text').html("");
|
||||
<?if (_var($var,'fsState')!="Stopped"):?>
|
||||
<?if (_var($var,'fsState') != "Stopped"):?>
|
||||
$('#spinup-button').prop('disabled',false);
|
||||
$('#spindown-button').prop('disabled',false);
|
||||
<?endif;?>
|
||||
<?if (_var($var,'shareUser')=='e' && $pool_devices):?>
|
||||
<?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;?>
|
||||
@@ -337,11 +398,11 @@ mymonitor.on('message', function(state) {
|
||||
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):?>
|
||||
<?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):?>
|
||||
<?if (_var($var,'shareUser') == 'e' && $pool_devices):?>
|
||||
$('#mover-button').prop('disabled',true);
|
||||
$('#mover-text').html("_(Disabled)_ -- _(Parity operation is running)_");
|
||||
<?endif;?>
|
||||
@@ -349,7 +410,7 @@ mymonitor.on('message', function(state) {
|
||||
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):?>
|
||||
<?if (_var($var,'shareUser') == 'e' && $pool_devices):?>
|
||||
$('#mover-button').prop('disabled',true);
|
||||
$('#mover-text').html("_(Disabled)_ - _(Mover is running)_.");
|
||||
<?endif;?>
|
||||
@@ -357,7 +418,7 @@ mymonitor.on('message', function(state) {
|
||||
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):?>
|
||||
<?if (_var($var,'shareUser') == 'e' && $pool_devices):?>
|
||||
$('#mover-button').prop('disabled',true);
|
||||
$('#mover-text').html("_(Disabled)_ -- _(BTRFS operation is running)_");
|
||||
<?endif;?>
|
||||
@@ -369,11 +430,11 @@ mymonitor.start();
|
||||
|
||||
var arraymonitor = new NchanSubscriber('/sub/arraymonitor',{subscriber:'websocket', reconnectTimeout:5000});
|
||||
arraymonitor.on('message', function(state) {
|
||||
if (state==1 && !timers.arraymonitor) timers.arraymonitor = setTimeout(refresh,1250);
|
||||
if (state == 1 && !timers.arraymonitor) timers.arraymonitor = setTimeout(refresh,1250);
|
||||
});
|
||||
|
||||
var devices = new NchanSubscriber('/sub/devices<?=$spot?",parity":""?>',{subscriber:'websocket', reconnectTimeout:5000});
|
||||
devices.on('message', function(msg,meta) {
|
||||
devices.on('message', function(msg, meta) {
|
||||
switch (<?if($spot):?>meta.id.channel()<?else:?>0<?endif;?>) {
|
||||
case 0:
|
||||
// array + pool + ua + flash devices
|
||||
@@ -382,9 +443,9 @@ devices.on('message', function(msg,meta) {
|
||||
if (recall !== null) recall.html(' ');
|
||||
display_diskio();
|
||||
// stop updating when array is stopped
|
||||
if (get.stop==1) {
|
||||
if (get.stop == 1) {
|
||||
$('thead tr').removeClass().addClass('offline');
|
||||
<?if (_var($var,'fsState')=='Started'):?>
|
||||
<?if (_var($var,'fsState') == 'Started'):?>
|
||||
setTimeout(refresh);
|
||||
<?else:?>
|
||||
if (!timers.stopped) timers.stopped = setTimeout(function(){devices.stop(); arraymonitor.start();},1500);
|
||||
@@ -402,17 +463,17 @@ devices.on('message', function(msg,meta) {
|
||||
var get = JSON.parse(msg);
|
||||
$.each(get,function(k,v) {if ($('#line'+k).length>0) $('#line'+k).html(v);});
|
||||
// button control
|
||||
if ($('#pauseButton').length>0 && $('#pauseButton').prop('disabled')==false) {
|
||||
if ((get === "") && $('#cancelButton').val()=="_(Cancel)_") {
|
||||
if ($('#pauseButton').length > 0 && $('#pauseButton').prop('disabled') == false) {
|
||||
if ((get === "") && $('#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)_" && get[1].search("_(paused)_")!=-1) {
|
||||
if ($('#pauseButton').val() == "_(Pause)_" && get[1].search("_(paused)_") != -1) {
|
||||
$('#pauseButton').val("_(Resume)_").prop('onclick',null).off('click').click(function(){resumeParity(form);});
|
||||
} else if ($('#pauseButton').val()=="_(Resume)_" && get[1].search("_(paused)_")==-1) {
|
||||
} else if ($('#pauseButton').val() == "_(Resume)_" && get[1].search("_(paused)_") == -1) {
|
||||
$('#pauseButton').val("_(Pause)_").prop('onclick',null).off('click').click(function(){pauseParity(form);});
|
||||
}
|
||||
}
|
||||
@@ -422,7 +483,7 @@ devices.on('message', function(msg,meta) {
|
||||
});
|
||||
devices.start().monitor();
|
||||
|
||||
<?if (substr(_var($var,'fsState'),-3)=='ing'):?>
|
||||
<?if (substr(_var($var,'fsState'),-3) == 'ing'):?>
|
||||
var fsState = new NchanSubscriber('/sub/fsState',{subscriber:'websocket', reconnectTimeout:5000});
|
||||
fsState.on('message', function(msg) {
|
||||
switch (msg) {
|
||||
@@ -439,7 +500,7 @@ fsState.start();
|
||||
setTimeout(function(){$('#pauseButton').prop('disabled',false);$('#cancelButton').prop('disabled',false);},250);
|
||||
<?else:?>
|
||||
var paritymonitor = new NchanSubscriber('/sub/paritymonitor',{subscriber:'websocket', reconnectTimeout:5000});
|
||||
paritymonitor.on('message', function(busy){if (busy==1) refresh();});
|
||||
paritymonitor.on('message', function(busy){if (busy == 1) refresh();});
|
||||
setTimeout(function(){paritymonitor.start();},5000);
|
||||
<?endif;?>
|
||||
|
||||
@@ -450,7 +511,7 @@ $(function(){
|
||||
});
|
||||
|
||||
function formatWarning(val) {
|
||||
if (val==true) {
|
||||
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)_. "+
|
||||
@@ -465,11 +526,11 @@ function formatWarning(val) {
|
||||
}
|
||||
|
||||
window.onunload = function(){
|
||||
<?if (_var($var,'fsState')=='Started'):?>
|
||||
<?if (_var($var,'fsState') == 'Started'):?>
|
||||
try {mymonitor.stop();} catch(e) {}
|
||||
try {devices.stop();} catch(e) {}
|
||||
<?endif;?>
|
||||
<?if ($spot==0):?>
|
||||
<?if ($spot == 0):?>
|
||||
try {paritymonitor.stop();} catch(e) {}
|
||||
<?endif;?>
|
||||
}
|
||||
@@ -483,42 +544,42 @@ window.onunload = function(){
|
||||
<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>
|
||||
<? 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(pool_name(_var($disk,'name')),$cache)) {
|
||||
foreach ($disks as $disk) if (substr(_var($disk,'fsStatus'),0,11) == 'Unmountable' || in_array(pool_name(_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>
|
||||
<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"):
|
||||
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):?>
|
||||
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"):?>
|
||||
<? 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;?>
|
||||
<? if (!$poolsOnly):?>
|
||||
<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):?>
|
||||
<? [$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):?>
|
||||
<? 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>
|
||||
@@ -528,7 +589,7 @@ window.onunload = function(){
|
||||
<br><i class="fa fa-fw fa-search"></i> <?=print_error($error)?></td></tr>
|
||||
<? endif;
|
||||
elseif (_var($var,'sbSynced2',0)==0):
|
||||
if ($status==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>
|
||||
@@ -545,24 +606,24 @@ window.onunload = function(){
|
||||
endif; // end check for poolsOnly
|
||||
endif;
|
||||
else:
|
||||
if ($action[0]=="recon"):
|
||||
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"):?>
|
||||
<? 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):?>
|
||||
<? 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"):?>
|
||||
<? 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>
|
||||
@@ -579,11 +640,11 @@ window.onunload = function(){
|
||||
<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>
|
||||
<? 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>
|
||||
<tr><td><?=_var($var,'mdResyncCorr') == 0 ? _('Read errors detected') : _('Read errors corrected')?>:</td><td id="line5"></td><td></td></tr>
|
||||
<? endif;
|
||||
endif;
|
||||
endif;
|
||||
@@ -610,19 +671,19 @@ window.onunload = function(){
|
||||
<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"):?>
|
||||
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"):?>
|
||||
<? 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')=="ineligible"):?>
|
||||
<? elseif (_var($var,'configValid') == "ineligible"):?>
|
||||
<tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
|
||||
<td>_(Ineligible to run this version of Unraid OS. Please consider extending your)_ <a href="/Tools/Registration">_(registration key)_</a>.</td></tr>
|
||||
<? elseif (_var($var,'configValid')=="nokeyserver"):?>
|
||||
<? 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"):?>
|
||||
<? 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:
|
||||
@@ -635,18 +696,18 @@ window.onunload = function(){
|
||||
break;
|
||||
case "STOPPED":
|
||||
$action = explode(' ',_var($var,'mdResyncAction'));
|
||||
if ($action[0]=="recon"):
|
||||
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"):?>
|
||||
<? 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):?>
|
||||
<? 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"):?>
|
||||
<? 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()):?>
|
||||
@@ -661,7 +722,7 @@ window.onunload = function(){
|
||||
check_encryption();
|
||||
break;
|
||||
case "NEW_ARRAY":
|
||||
if (strpos(_var($disks['parity'],'status'),"DISK_NP")===0 && strpos(_var($disks['parity2'],'status'),"DISK_NP")===0):?>
|
||||
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>
|
||||
@@ -688,7 +749,7 @@ window.onunload = function(){
|
||||
check_encryption();
|
||||
break;
|
||||
case "SWAP_DSBL":
|
||||
if (_var($var,'fsCopyPrcnt')=="100"):?>
|
||||
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();
|
||||
@@ -731,7 +792,7 @@ endswitch;
|
||||
<tr><td></td><td class="line" colspan="2"></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<?if (_var($var,'fsState')!="Stopped"):?>
|
||||
<?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">
|
||||
@@ -749,7 +810,7 @@ endswitch;
|
||||
<tr id="clearstats" class="hidden"><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):?>
|
||||
<?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>
|
||||
@@ -776,7 +837,7 @@ endswitch;
|
||||
<!-- markdown fix --></p><?if (isset($display['sleep'])) eval('?>'.parse_file($display['sleep']))?>
|
||||
|
||||
:array_status_help:
|
||||
<?if (_var($var,'fsState')=="Stopped"):?>
|
||||
<?if (_var($var,'fsState') == "Stopped"):?>
|
||||
:array_devices_help:
|
||||
|
||||
<?if ($encrypt):?>
|
||||
|
||||
@@ -31,6 +31,7 @@ String.prototype.celsius = function(){return Math.round((parseInt(this)-32)*5/9)
|
||||
function base64(str) {
|
||||
return window.btoa(unescape(encodeURIComponent(str)));
|
||||
}
|
||||
|
||||
function doDispatch(form) {
|
||||
var fields = {};
|
||||
<?if ($display['unit']=='F'):?>
|
||||
@@ -45,6 +46,7 @@ function doDispatch(form) {
|
||||
$(form).find('select[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++) {
|
||||
@@ -58,26 +60,44 @@ function prepareDiskSettings(form) {
|
||||
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;
|
||||
}
|
||||
|
||||
function prepareForm(form) {
|
||||
<?if (!$keyfile):?>
|
||||
form.oldluks.value = base64(form.oldtext.value);
|
||||
form.oldluks.value = base64(form.oldtext.value.replace(/\\"/g,'"'));
|
||||
form.oldtext.disabled = true;
|
||||
form.oldfile.disabled = true;
|
||||
<?endif;?>
|
||||
form.newluks.value = base64(form.newtext.value);
|
||||
form.newtext.disabled = true;
|
||||
form.newcopy.disabled = true;
|
||||
form.newfile.disabled = true;
|
||||
var valid = new RegExp('^[ -~]+$');
|
||||
if (form.newinput.value == 'file') return true;
|
||||
if (valid.test(form.newtext.value)) {
|
||||
form.newluks.value = base64(form.newtext.value.replace(/\\"/g,'"'));
|
||||
form.newtext.disabled = true;
|
||||
form.newcopy.disabled = true;
|
||||
form.newfile.disabled = true;
|
||||
return true;
|
||||
} else {
|
||||
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 false;
|
||||
}
|
||||
}
|
||||
|
||||
function getFileContent(event,form,file) {
|
||||
var input = event.target;
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(){$(form).find('input[name="'+file+'"]').val(reader.result);};
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
}
|
||||
|
||||
function selectInput(val,old) {
|
||||
if (val=='text') {
|
||||
if (old==true) {
|
||||
@@ -86,7 +106,7 @@ function selectInput(val,old) {
|
||||
} else {
|
||||
$('div#newfile').hide('slow');
|
||||
$('div#newtext').show('slow');
|
||||
$('input[name="newkey"]').prop('disabled',$('input[name="newtext"]').val()=='' || $('input[name="newtext"]').val()!=$('input[name="newcopy"]').val());
|
||||
$('input[name="newkey"]').prop('disabled',$('input[name="newtext"]').val() == '' || $('input[name="newtext"]').val() != $('input[name="newcopy"]').val());
|
||||
}
|
||||
} else if (val=='file') {
|
||||
if (old==true) {
|
||||
@@ -95,25 +115,34 @@ function selectInput(val,old) {
|
||||
} else {
|
||||
$('div#newtext').hide('slow');
|
||||
$('div#newfile').show('slow');
|
||||
$('input[name="newkey"]').prop('disabled',$('input[name="newfile"]').val()=='');
|
||||
$('input[name="newkey"]').prop('disabled',$('input[name="newfile"]').val() == '');
|
||||
}
|
||||
}
|
||||
}
|
||||
function showInput(show,old) {
|
||||
|
||||
function showInput(show, old) {
|
||||
if (old==true) {
|
||||
var input = $('input[name="oldtext"]');
|
||||
} else {
|
||||
var input = $('input[name="newtext"],input[name="newcopy"]');
|
||||
}
|
||||
input.attr('type',show ? 'text' : 'password');
|
||||
input.attr('type', show ? 'text' : 'password');
|
||||
}
|
||||
|
||||
function checkInput(form) {
|
||||
$(form).find('input[name="newkey"]').prop('disabled',form.newtext.value=='' || form.newtext.value!=form.newcopy.value);
|
||||
$(form).find('input[name="newkey"]').prop('disabled',form.newtext.value == '' || form.newtext.value != form.newcopy.value);
|
||||
}
|
||||
|
||||
<?if (is_file($reply)):?>
|
||||
<?[$text,$type] = explode("\0",file_get_contents($reply)); unlink($reply);?>
|
||||
$(function() {
|
||||
swal({title:"_(Encryption Key Update)_",text:"<?=$text?>",html:true,type:"<?=$type?>",confirmButtonText:"_(Ok)_"});
|
||||
swal({
|
||||
title:"_(Encryption Key Update)_",
|
||||
text:"<?=$text?>",
|
||||
html:true,
|
||||
type:"<?=$type?>",
|
||||
confirmButtonText:"_(Ok)_"
|
||||
});
|
||||
});
|
||||
<?endif;?>
|
||||
</script>
|
||||
@@ -275,7 +304,7 @@ _(Default critical SSD temperature threshold)_ (°<?=_var($display,'unit','C'
|
||||
<i class="title fa fa-key"></i>_(Change encryption key)_
|
||||
</span>
|
||||
</div>
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareForm(this)">
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame" onsubmit="return prepareForm(this)">
|
||||
<input type="hidden" name="#file" value="">
|
||||
<input type="hidden" name="#include" value="/webGui/include/update.encryption.php">
|
||||
<input type="hidden" name="#reply" value="<?=$reply?>">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
/* Copyright 2005-2025, Lime Technology
|
||||
* Copyright 2012-2025, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -17,121 +17,149 @@ require_once "$docroot/webGui/include/Secure.php";
|
||||
|
||||
// Helper functions
|
||||
function my_scale($value, &$unit, $decimals=NULL, $scale=NULL, $kilo=1000) {
|
||||
global $display,$language;
|
||||
global $display, $language;
|
||||
$scale = $scale ?? $display['scale'];
|
||||
$number = _var($display,'number','.,');
|
||||
$units = explode(' ', ' '.($kilo==1000 ? ($language['prefix_SI'] ?? 'K M G T P E Z Y') : ($language['prefix_IEC'] ?? 'Ki Mi Gi Ti Pi Ei Zi Yi')));
|
||||
$size = count($units);
|
||||
if ($scale==0 && ($decimals===NULL || $decimals<0)) {
|
||||
if ($scale == 0 && ($decimals === NULL || $decimals < 0)) {
|
||||
$decimals = 0;
|
||||
$unit = '';
|
||||
} else {
|
||||
$base = $value ? intval(floor(log($value, $kilo))) : 0;
|
||||
if ($scale>0 && $base>$scale) $base = $scale;
|
||||
if ($base>$size) $base = $size-1;
|
||||
if ($scale > 0 && $base > $scale) $base = $scale;
|
||||
if ($base > $size) $base = $size - 1;
|
||||
$value /= pow($kilo, $base);
|
||||
if ($decimals===NULL) $decimals = $value>=100 ? 0 : ($value>=10 ? 1 : (round($value*100)%100===0 ? 0 : 2));
|
||||
elseif ($decimals<0) $decimals = $value>=100||round($value*10)%10===0 ? 0 : abs($decimals);
|
||||
if ($scale<0 && round($value,-1)==1000) {$value = 1; $base++;}
|
||||
if ($decimals === NULL) $decimals = $value >= 100 ? 0 : ($value >= 10 ? 1 : (round($value*100)%100 === 0 ? 0 : 2));
|
||||
elseif ($decimals < 0) $decimals = $value >= 100 || round($value*10)%10 === 0 ? 0 : abs($decimals);
|
||||
if ($scale < 0 && round($value,-1) == 1000) {$value = 1; $base++;}
|
||||
$unit = $units[$base]._('B');
|
||||
}
|
||||
return number_format($value, $decimals, $number[0], $value>9999 ? $number[1] : '');
|
||||
return number_format($value, $decimals, $number[0], $value > 9999 ? $number[1] : '');
|
||||
}
|
||||
|
||||
function my_number($value) {
|
||||
global $display;
|
||||
$number = _var($display,'number','.,');
|
||||
return number_format($value, 0, $number[0], ($value>=10000 ? $number[1] : ''));
|
||||
return number_format($value, 0, $number[0], ($value >= 10000 ? $number[1] : ''));
|
||||
}
|
||||
|
||||
function my_time($time, $fmt=NULL) {
|
||||
global $display;
|
||||
if (!$fmt) $fmt = _var($display,'date').(_var($display,'date')!='%c' ? ", "._var($display,'time') : "");
|
||||
return $time ? my_date($fmt, $time) : _('unknown');
|
||||
}
|
||||
|
||||
function my_temp($value) {
|
||||
global $display;
|
||||
$unit = _var($display,'unit','C');
|
||||
$number = _var($display,'number','.,');
|
||||
return is_numeric($value) ? (($unit=='F' ? fahrenheit($value) : str_replace('.', $number[0], $value)).' °'.$unit) : $value;
|
||||
return is_numeric($value) ? (($unit == 'F' ? fahrenheit($value) : str_replace('.', $number[0], $value)).' °'.$unit) : $value;
|
||||
}
|
||||
|
||||
function my_disk($name, $raw=false) {
|
||||
global $display;
|
||||
return _var($display,'raw')||$raw ? $name : ucfirst(preg_replace('/(\d+)$/',' $1',$name));
|
||||
return _var($display,'raw') || $raw ? $name : ucfirst(preg_replace('/(\d+)$/',' $1',$name));
|
||||
}
|
||||
|
||||
function my_disks($disk) {
|
||||
return strpos(_var($disk,'status'),'_NP')===false;
|
||||
return strpos(_var($disk,'status'),'_NP') === false;
|
||||
}
|
||||
|
||||
function my_hyperlink($text, $link) {
|
||||
return str_replace(['[',']'],["<a href=\"$link\">","</a>"],$text);
|
||||
}
|
||||
|
||||
function main_only($disk) {
|
||||
return _var($disk,'type')=='Parity' || _var($disk,'type')=='Data';
|
||||
return _var($disk,'type') == 'Parity' || _var($disk,'type') == 'Data';
|
||||
}
|
||||
|
||||
function parity_only($disk) {
|
||||
return _var($disk,'type')=='Parity';
|
||||
return _var($disk,'type') == 'Parity';
|
||||
}
|
||||
|
||||
function data_only($disk) {
|
||||
return _var($disk,'type')=='Data';
|
||||
return _var($disk,'type') == 'Data';
|
||||
}
|
||||
|
||||
function cache_only($disk) {
|
||||
return _var($disk,'type')=='Cache';
|
||||
return _var($disk,'type') == 'Cache';
|
||||
}
|
||||
|
||||
function luks_only($disk) {
|
||||
return _var($disk,'type') == 'Data' || _var($disk,'type') == 'Cache';
|
||||
}
|
||||
|
||||
function main_filter($disks) {
|
||||
return array_filter($disks,'main_only');
|
||||
return array_filter($disks, 'main_only');
|
||||
}
|
||||
|
||||
function parity_filter($disks) {
|
||||
return array_filter($disks,'parity_only');
|
||||
return array_filter($disks, 'parity_only');
|
||||
}
|
||||
|
||||
function data_filter($disks) {
|
||||
return array_filter($disks,'data_only');
|
||||
return array_filter($disks, 'data_only');
|
||||
}
|
||||
|
||||
function cache_filter($disks) {
|
||||
return array_filter($disks,'cache_only');
|
||||
return array_filter($disks, 'cache_only');
|
||||
}
|
||||
|
||||
function luks_filter($disks) {
|
||||
return array_filter($disks, 'luks_only');
|
||||
}
|
||||
|
||||
function pools_filter($disks) {
|
||||
return array_unique(array_map('prefix',array_keys(cache_filter($disks))));
|
||||
return array_unique(array_map('prefix', array_keys(cache_filter($disks))));
|
||||
}
|
||||
|
||||
function my_id($id) {
|
||||
global $display;
|
||||
$len = strlen($id);
|
||||
$wwn = substr($id,-18);
|
||||
return (_var($display,'wwn') || substr($wwn,0,2)!='_3' || preg_match('/.[_-]/',$wwn)) ? $id : substr($id,0,$len-18);
|
||||
return (_var($display,'wwn') || substr($wwn,0,2) != '_3' || preg_match('/.[_-]/',$wwn)) ? $id : substr($id,0,$len-18);
|
||||
}
|
||||
|
||||
function my_word($num) {
|
||||
$words = ['zero','one','two','three','four','five','six','seven','eight','nine','ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen','twenty','twenty-one','twenty-two','twenty-three','twenty-four','twenty-five','twenty-six','twenty-seven','twenty-eight','twenty-nine','thirty'];
|
||||
return $num<count($words) ? _($words[$num],1) : $num;
|
||||
return $num < count($words) ? _($words[$num],1) : $num;
|
||||
}
|
||||
|
||||
function my_usage() {
|
||||
global $disks,$var,$display;
|
||||
$arraysize=0;
|
||||
$arrayfree=0;
|
||||
global $disks, $var, $display;
|
||||
$arraysize = 0;
|
||||
$arrayfree = 0;
|
||||
foreach ($disks as $disk) {
|
||||
if (strpos(_var($disk,'name'),'disk')!==false) {
|
||||
if (strpos(_var($disk,'name'),'disk') !== false) {
|
||||
$arraysize += _var($disk,'sizeSb',0);
|
||||
$arrayfree += _var($disk,'fsFree',0);
|
||||
}
|
||||
}
|
||||
if (_var($var,'fsNumMounted',0)>0) {
|
||||
if (_var($var,'fsNumMounted',0) > 0) {
|
||||
$used = $arraysize ? 100-round(100*$arrayfree/$arraysize) : 0;
|
||||
echo "<div class='usage-bar'><span style='width:{$used}%' class='".usage_color($display,$used,false)."'>{$used}%</span></div>";
|
||||
} else {
|
||||
echo "<div class='usage-bar'><span style='text-align:center'>".($var['fsState']=='Started'?'Maintenance':'off-line')."</span></div>";
|
||||
}
|
||||
}
|
||||
|
||||
function usage_color(&$disk, $limit, $free) {
|
||||
global $display;
|
||||
if (_var($display,'text',0)==1 || intval(_var($display,'text',0)/10)==1) return '';
|
||||
$critical = _var($disk,'critical')>=0 ? $disk['critical'] : (_var($display,'critical')>=0 ? $display['critical'] : 0);
|
||||
$warning = _var($disk,'warning')>=0 ? $disk['warning'] : (_var($display,'warning')>=0 ? $display['warning'] : 0);
|
||||
if (_var($display,'text',0) == 1 || intval(_var($display,'text',0)/10) == 1) return '';
|
||||
$critical = _var($disk,'critical') >= 0 ? $disk['critical'] : (_var($display,'critical') >= 0 ? $display['critical'] : 0);
|
||||
$warning = _var($disk,'warning') >= 0 ? $disk['warning'] : (_var($display,'warning') >= 0 ? $display['warning'] : 0);
|
||||
if (!$free) {
|
||||
if ($critical>0 && $limit>=$critical) return 'redbar';
|
||||
if ($warning>0 && $limit>=$warning) return 'orangebar';
|
||||
if ($critical > 0 && $limit >= $critical) return 'redbar';
|
||||
if ($warning > 0 && $limit >= $warning) return 'orangebar';
|
||||
return 'greenbar';
|
||||
} else {
|
||||
if ($critical>0 && $limit<=100-$critical) return 'redbar';
|
||||
if ($warning>0 && $limit<=100-$warning) return 'orangebar';
|
||||
if ($critical > 0 && $limit <= 100-$critical) return 'redbar';
|
||||
if ($warning > 0 && $limit <= 100-$warning) return 'orangebar';
|
||||
return 'greenbar';
|
||||
}
|
||||
}
|
||||
|
||||
function my_check($time, $speed) {
|
||||
if (!$time) return _('unavailable (no parity-check entries logged)');
|
||||
$days = floor($time/86400);
|
||||
@@ -139,8 +167,9 @@ function my_check($time, $speed) {
|
||||
$hour = floor($hmss/3600);
|
||||
$mins = floor($hmss/60)%60;
|
||||
$secs = $hmss%60;
|
||||
return plus($days,'day',($hour|$mins|$secs)==0).plus($hour,'hour',($mins|$secs)==0).plus($mins,'minute',$secs==0).plus($secs,'second',true).". "._('Average speed').": ".(is_numeric($speed) ? my_scale($speed,$unit,1)." $unit/s" : $speed);
|
||||
return plus($days,'day',($hour|$mins|$secs) == 0).plus($hour,'hour',($mins|$secs) == 0).plus($mins,'minute',$secs == 0).plus($secs,'second',true).". "._('Average speed').": ".(is_numeric($speed) ? my_scale($speed,$unit,1)." $unit/s" : $speed);
|
||||
}
|
||||
|
||||
function my_error($code) {
|
||||
switch ($code) {
|
||||
case -4:
|
||||
@@ -149,25 +178,29 @@ function my_error($code) {
|
||||
return "<strong>$code</strong>";
|
||||
}
|
||||
}
|
||||
|
||||
function mk_option($select, $value, $text, $extra="") {
|
||||
return "<option value='$value'".($value==$select ? " selected" : "").(strlen($extra) ? " $extra" : "").">$text</option>";
|
||||
return "<option value='$value'".($value == $select ? " selected" : "").(strlen($extra) ? " $extra" : "").">$text</option>";
|
||||
}
|
||||
|
||||
function mk_option_check($name, $value, $text="") {
|
||||
if ($text) {
|
||||
$checked = in_array($value,explode(',',$name)) ? " selected" : "";
|
||||
return "<option value='$value'$checked>$text</option>";
|
||||
}
|
||||
if (strpos($name,'disk')!==false) {
|
||||
if (strpos($name,'disk') !== false) {
|
||||
$checked = in_array($name,explode(',',$value)) ? " selected" : "";
|
||||
return "<option value='$name'$checked>".my_disk($name)."</option>";
|
||||
}
|
||||
}
|
||||
|
||||
function mk_option_luks($name, $value, $luks) {
|
||||
if (strpos($name,'disk')!==false) {
|
||||
if (strpos($name,'disk') !== false) {
|
||||
$checked = in_array($name,explode(',',$value)) ? " selected" : "";
|
||||
return "<option luks='$luks' value='$name'$checked>".my_disk($name)."</option>";
|
||||
}
|
||||
}
|
||||
|
||||
function day_count($time) {
|
||||
global $var;
|
||||
if (!$time) return;
|
||||
@@ -178,29 +211,33 @@ function day_count($time) {
|
||||
$last = new DateTime("@".intval(($time+$offset)/86400)*86400);
|
||||
$days = date_diff($last,$now)->format('%a');
|
||||
switch (true) {
|
||||
case ($days<0):
|
||||
case ($days < 0):
|
||||
return;
|
||||
case ($days==0):
|
||||
case ($days == 0):
|
||||
return " <span class='green-text'>("._('today').")</span>";
|
||||
case ($days==1):
|
||||
case ($days == 1):
|
||||
return " <span class='green-text'>("._('yesterday').")</span>";
|
||||
case ($days<=31):
|
||||
case ($days <= 31):
|
||||
return " <span class='green-text'>(".sprintf(_('%s days ago'),my_word($days)).")</span>";
|
||||
case ($days<=61):
|
||||
case ($days <= 61):
|
||||
return " <span class='orange-text'>(".sprintf(_('%s days ago'),$days).")</span>";
|
||||
case ($days>61):
|
||||
case ($days > 61):
|
||||
return " <span class='red-text'>(".sprintf(_('%s days ago'),$days).")</span>";
|
||||
}
|
||||
}
|
||||
|
||||
function plus($val, $word, $last) {
|
||||
return $val>0 ? (($val || $last) ? ($val.' '._($word.($val!=1?'s':'')).($last ?'':', ')) : '') : '';
|
||||
return $val > 0 ? (($val || $last) ? ($val.' '._($word.($val != 1 ? 's' : '')).($last ? '' : ', ')) : '') : '';
|
||||
}
|
||||
|
||||
function compress($name, $size=18, $end=6) {
|
||||
return mb_strlen($name)<=$size ? $name : mb_substr($name,0,$size-($end?$end+3:0)).'...'.($end?mb_substr($name,-$end):'');
|
||||
return mb_strlen($name) <= $size ? $name : mb_substr($name, 0, $size-($end ? $end+3 : 0)).'...'.($end ? mb_substr($name,-$end) : '');
|
||||
}
|
||||
|
||||
function escapestring($name) {
|
||||
return "\"$name\"";
|
||||
}
|
||||
|
||||
function tail($file, $rows=1) {
|
||||
$file = new SplFileObject($file);
|
||||
$file->seek(PHP_INT_MAX);
|
||||
@@ -215,61 +252,59 @@ function tail($file, $rows=1) {
|
||||
|
||||
/* Get the last parity check from the parity history. */
|
||||
function last_parity_log() {
|
||||
$log = '/boot/config/parity-checks.log';
|
||||
|
||||
if (file_exists($log)) {
|
||||
list($date, $duration, $speed, $status, $error, $action, $size) = my_explode('|', tail($log), 7);
|
||||
} else {
|
||||
list($date, $duration, $speed, $status, $error, $action, $size) = array_fill(0, 7, 0);
|
||||
}
|
||||
|
||||
if ($date) {
|
||||
list($y, $m, $d, $t) = my_preg_split('/ +/', $date, 4);
|
||||
$date = strtotime("$d-$m-$y $t");
|
||||
}
|
||||
|
||||
return [$date, $duration, $speed, $status, $error, $action, $size];
|
||||
$log = '/boot/config/parity-checks.log';
|
||||
if (file_exists($log)) {
|
||||
[$date, $duration, $speed, $status, $error, $action, $size] = my_explode('|', tail($log), 7);
|
||||
} else {
|
||||
[$date, $duration, $speed, $status, $error, $action, $size] = array_fill(0, 7, 0);
|
||||
}
|
||||
if ($date) {
|
||||
[$y, $m, $d, $t] = my_preg_split('/ +/', $date, 4);
|
||||
$date = strtotime("$d-$m-$y $t");
|
||||
}
|
||||
return [$date, $duration, $speed, $status, $error, $action, $size];
|
||||
}
|
||||
|
||||
|
||||
/* Get the last parity check from Unraid. */
|
||||
function last_parity_check() {
|
||||
global $var;
|
||||
|
||||
/* Files for the latest parity check. */
|
||||
$stamps = '/var/tmp/stamps.ini';
|
||||
$resync = '/var/tmp/resync.ini';
|
||||
|
||||
/* Get the latest parity information from Unraid. */
|
||||
$synced = file_exists($stamps) ? explode(',',file_get_contents($stamps)) : [];
|
||||
$sbSynced = array_shift($synced) ?: _var($var,'sbSynced',0);
|
||||
$idle = [];
|
||||
while (count($synced) > 1) {
|
||||
$idle[] = array_pop($synced) - array_pop($synced);
|
||||
}
|
||||
$action = _var($var, 'mdResyncAction');
|
||||
$size = _var($var, 'mdResyncSize', 0);
|
||||
if (file_exists($resync)) {
|
||||
list($action, $size) = my_explode(',', file_get_contents($resync));
|
||||
}
|
||||
$duration = $var['sbSynced2']-$sbSynced-array_sum($idle);
|
||||
$status = _var($var,'sbSyncExit');
|
||||
$speed = $status==0 ? round($size*1024/$duration) : 0;
|
||||
$error = _var($var,'sbSyncErrs',0);
|
||||
|
||||
return [$duration, $speed, $status, $error, $action, $size];
|
||||
global $var;
|
||||
/* Files for the latest parity check. */
|
||||
$stamps = '/var/tmp/stamps.ini';
|
||||
$resync = '/var/tmp/resync.ini';
|
||||
/* Get the latest parity information from Unraid. */
|
||||
$synced = file_exists($stamps) ? explode(',',file_get_contents($stamps)) : [];
|
||||
$sbSynced = array_shift($synced) ?: _var($var,'sbSynced',0);
|
||||
$idle = [];
|
||||
while (count($synced) > 1) {
|
||||
$idle[] = array_pop($synced) - array_pop($synced);
|
||||
}
|
||||
$action = _var($var, 'mdResyncAction');
|
||||
$size = _var($var, 'mdResyncSize', 0);
|
||||
if (file_exists($resync)) {
|
||||
list($action, $size) = my_explode(',', file_get_contents($resync));
|
||||
}
|
||||
$duration = $var['sbSynced2']-$sbSynced-array_sum($idle);
|
||||
$status = _var($var,'sbSyncExit');
|
||||
$speed = $status==0 ? round($size*1024/$duration) : 0;
|
||||
$error = _var($var,'sbSyncErrs',0);
|
||||
return [$duration, $speed, $status, $error, $action, $size];
|
||||
}
|
||||
|
||||
function urlencode_path($path) {
|
||||
return str_replace("%2F", "/", urlencode($path));
|
||||
}
|
||||
|
||||
function pgrep($process_name, $escape_arg=true) {
|
||||
$pid = exec('pgrep --ns $$ '.($escape_arg?escapeshellarg($process_name):$process_name), $output, $retval);
|
||||
return $retval==0 ? $pid : false;
|
||||
$pid = exec('pgrep --ns $$ '.($escape_arg ? escapeshellarg($process_name) : $process_name), $output, $retval);
|
||||
return $retval == 0 ? $pid : false;
|
||||
}
|
||||
|
||||
function is_block($path) {
|
||||
return (@filetype(realpath($path))=='block');
|
||||
return (@filetype(realpath($path)) == 'block');
|
||||
}
|
||||
function autov($file,$ret=false) {
|
||||
|
||||
function autov($file, $ret=false) {
|
||||
global $docroot;
|
||||
$path = $docroot.$file;
|
||||
clearstatcache(true, $path);
|
||||
@@ -280,28 +315,34 @@ function autov($file,$ret=false) {
|
||||
else
|
||||
echo $newFile;
|
||||
}
|
||||
|
||||
function transpose_user_path($path) {
|
||||
if (strpos($path,'/mnt/user/')===0 && file_exists($path)) {
|
||||
if (strpos($path,'/mnt/user/') === 0 && file_exists($path)) {
|
||||
$realdisk = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($path)." 2>/dev/null"));
|
||||
if (!empty($realdisk))
|
||||
$path = str_replace('/mnt/user/', "/mnt/$realdisk/", $path);
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
function cpu_list() {
|
||||
exec('cat /sys/devices/system/cpu/*/topology/thread_siblings_list|sort -nu', $cpus);
|
||||
return $cpus;
|
||||
}
|
||||
|
||||
function my_explode($split, $text, $count=2) {
|
||||
return array_pad(explode($split,$text,$count),$count,'');
|
||||
return array_pad(explode($split, $text, $count), $count, '');
|
||||
}
|
||||
|
||||
function my_preg_split($split, $text, $count=2) {
|
||||
return array_pad(preg_split($split,$text,$count),$count,'');
|
||||
return array_pad(preg_split($split, $text, $count), $count, '');
|
||||
}
|
||||
|
||||
function delete_file(...$file) {
|
||||
array_map('unlink',array_filter($file,'file_exists'));
|
||||
array_map('unlink', array_filter($file,'file_exists'));
|
||||
}
|
||||
function my_mkdir($dirname,$permissions = 0777,$recursive = false,$own = "nobody",$grp = "users") {
|
||||
|
||||
function my_mkdir($dirname, $permissions=0777, $recursive=false, $own="nobody", $grp="users") {
|
||||
write_logging("Check if dir exists\n");
|
||||
if (is_dir($dirname)) {write_logging("Dir exists\n"); return(false);}
|
||||
write_logging("Dir does not exist\n");
|
||||
@@ -314,7 +355,7 @@ function my_mkdir($dirname,$permissions = 0777,$recursive = false,$own = "nobody
|
||||
$parent = $pathinfo2["dirname"];
|
||||
}
|
||||
write_logging("Parent $parent\n");
|
||||
if (strpos($dirname,'/mnt/user/')===0) {
|
||||
if (strpos($dirname,'/mnt/user/') === 0) {
|
||||
write_logging("Getting real disks\n");
|
||||
$realdisk = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($parent)." 2>/dev/null"));
|
||||
if (!empty($realdisk)) {
|
||||
@@ -329,21 +370,21 @@ function my_mkdir($dirname,$permissions = 0777,$recursive = false,$own = "nobody
|
||||
case "zfs":
|
||||
if (is_dir($parent.'/.zfs')) {
|
||||
write_logging("ZFS Volume\n");
|
||||
$zfsdataset = trim(shell_exec("zfs list -H -o name $parent"));
|
||||
$zfsdataset = trim(shell_exec("zfs list -H -o name $parent"));
|
||||
write_logging("Shell $zfsdataset\n");
|
||||
$zfsdataset .= str_replace($parent,"",$dirname);
|
||||
write_logging("Dataset $zfsdataset\n");
|
||||
$zfsoutput = array();
|
||||
if ($recursive) exec("zfs create -p \"$zfsdataset\"",$zfsoutput,$rtncode);else exec("zfs create \"$zfsdataset\"",$zfsoutput,$rtncode);
|
||||
write_logging("Output: {$zfsoutput[0]} $rtncode");
|
||||
if ($recursive) exec("zfs create -p \"$zfsdataset\"",$zfsoutput,$rtncode);else exec("zfs create \"$zfsdataset\"", $zfsoutput, $rtncode);
|
||||
write_logging("Output: {$zfsoutput[0]} $rtncode");
|
||||
if ($rtncode == 0) write_logging( " ZFS Command OK\n"); else write_logging( "ZFS Command Fail\n");
|
||||
} else {write_logging("Not ZFS dataset\n");$rtncode = 1;}
|
||||
if ($rtncode > 0) { mkdir($dirname, $permissions, $recursive); write_logging( "created dir:$dirname\n");} else chmod($zfsdataset,$permissions);
|
||||
if ($rtncode > 0) { mkdir($dirname, $permissions, $recursive); write_logging( "created dir:$dirname\n");} else chmod($zfsdataset, $permissions);
|
||||
break;
|
||||
case "btrfs":
|
||||
$btrfsoutput = array();
|
||||
if ($recursive) exec("btrfs subvolume create --parents \"$dirname\"",$btrfsoutput,$rtncode); else exec("btrfs subvolume create \"$dirname\"",$btrfsoutput,$rtncode);
|
||||
if ($rtncode > 0) mkdir($dirname, $permissions, $recursive); else chmod($dirname,$permissions);
|
||||
if ($recursive) exec("btrfs subvolume create --parents \"$dirname\"",$btrfsoutput,$rtncode); else exec("btrfs subvolume create \"$dirname\"", $btrfsoutput, $rtncode);
|
||||
if ($rtncode > 0) mkdir($dirname, $permissions, $recursive); else chmod($dirname, $permissions);
|
||||
break;
|
||||
default:
|
||||
mkdir($dirname, $permissions, $recursive);
|
||||
@@ -353,6 +394,7 @@ function my_mkdir($dirname,$permissions = 0777,$recursive = false,$own = "nobody
|
||||
chgrp($dirname, $grp);
|
||||
return($rtncode);
|
||||
}
|
||||
|
||||
function my_rmdir($dirname) {
|
||||
if (!is_dir("$dirname")) {
|
||||
$return = [
|
||||
@@ -361,7 +403,7 @@ function my_rmdir($dirname) {
|
||||
];
|
||||
return($return);
|
||||
}
|
||||
if (strpos($dirname,'/mnt/user/')===0) {
|
||||
if (strpos($dirname,'/mnt/user/') === 0) {
|
||||
$realdisk = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($dirname)." 2>/dev/null"));
|
||||
if (!empty($realdisk)) {
|
||||
$dirname = str_replace('/mnt/user/', "/mnt/$realdisk/", "$dirname");
|
||||
@@ -395,9 +437,10 @@ function my_rmdir($dirname) {
|
||||
}
|
||||
return($return);
|
||||
}
|
||||
|
||||
function get_realvolume($path) {
|
||||
if (strpos($path,"/mnt/user/",0) === 0)
|
||||
$reallocation = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($path)." 2>/dev/null"));
|
||||
if (strpos($path,"/mnt/user/",0) === 0)
|
||||
$reallocation = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($path)." 2>/dev/null"));
|
||||
else {
|
||||
$realexplode = explode("/",str_replace("/mnt/","",$path));
|
||||
$reallocation = $realexplode[0];
|
||||
@@ -411,13 +454,11 @@ function write_logging($value) {
|
||||
file_put_contents('/tmp/my_mkdir_output', $value, FILE_APPEND);
|
||||
}
|
||||
|
||||
function device_exists($name)
|
||||
{
|
||||
global $disks,$devs;
|
||||
function device_exists($name) {
|
||||
global $disks, $devs;
|
||||
return (array_key_exists($name, $disks) && !str_contains(_var($disks[$name],'status'),'_NP')) || (array_key_exists($name, $devs));
|
||||
}
|
||||
|
||||
|
||||
# Check for process Core Types.
|
||||
function parse_cpu_ranges($file) {
|
||||
if (!is_file($file)) return null;
|
||||
@@ -425,12 +466,12 @@ function parse_cpu_ranges($file) {
|
||||
$ranges = trim($ranges);
|
||||
$cores = [];
|
||||
foreach (explode(',', $ranges) as $range) {
|
||||
if (strpos($range, '-') !== false) {
|
||||
list($start, $end) = explode('-', $range);
|
||||
$cores = array_merge($cores, range((int)$start, (int)$end));
|
||||
} else {
|
||||
$cores[] = (int)$range;
|
||||
}
|
||||
if (strpos($range, '-') !== false) {
|
||||
list($start, $end) = explode('-', $range);
|
||||
$cores = array_merge($cores, range((int)$start, (int)$end));
|
||||
} else {
|
||||
$cores[] = (int)$range;
|
||||
}
|
||||
}
|
||||
return $cores;
|
||||
}
|
||||
@@ -454,32 +495,32 @@ function get_intel_core_types() {
|
||||
return $core_types;
|
||||
}
|
||||
|
||||
function dmidecode($key,$n,$all=true) {
|
||||
$entries = array_filter(explode($key,shell_exec("dmidecode -qt$n")??""));
|
||||
function dmidecode($key, $n, $all=true) {
|
||||
$entries = array_filter(explode($key, shell_exec("dmidecode -qt$n")??""));
|
||||
$properties = [];
|
||||
foreach ($entries as $entry) {
|
||||
$property = [];
|
||||
foreach (explode("\n",$entry) as $line) if (strpos($line,': ')!==false) {
|
||||
[$key,$value] = my_explode(': ',trim($line));
|
||||
foreach (explode("\n",$entry) as $line) if (strpos($line,': ') !== false) {
|
||||
[$key, $value] = my_explode(': ',trim($line));
|
||||
$property[$key] = $value;
|
||||
}
|
||||
$properties[] = $property;
|
||||
}
|
||||
return $all ? $properties : $properties[0]??null;
|
||||
return $all ? $properties : $properties[0] ?? null;
|
||||
}
|
||||
|
||||
function is_intel_cpu() {
|
||||
$cpu = dmidecode('Processor Information','4',0);
|
||||
$cpu = dmidecode('Processor Information','4',0);
|
||||
$cpu_vendor = $cpu['Manufacturer'] ?? "";
|
||||
$is_intel_cpu = stripos($cpu_vendor, "intel") !== false ? true : false;
|
||||
return $is_intel_cpu;
|
||||
}
|
||||
|
||||
// Load saved PCI data
|
||||
function loadSavedData($filename) {
|
||||
if (file_exists($filename)) {
|
||||
$saveddata = file_get_contents($filename);
|
||||
} else $saveddata = "";
|
||||
|
||||
return json_decode($saveddata, true);
|
||||
}
|
||||
|
||||
@@ -487,26 +528,21 @@ function loadSavedData($filename) {
|
||||
function loadCurrentPCIData() {
|
||||
$output = shell_exec('lspci -Dmn');
|
||||
$devices = [];
|
||||
|
||||
if (file_exists("/boot/config/current.json")){
|
||||
$devices = loadSavedData("/boot/config/current.json");
|
||||
if (file_exists("/boot/config/current.json")) {
|
||||
$devices = loadSavedData("/boot/config/current.json");
|
||||
} else {
|
||||
foreach (explode("\n", trim($output)) as $line) {
|
||||
$parts = explode(" ", $line);
|
||||
|
||||
if (count($parts) < 6) continue; // Skip malformed lines
|
||||
|
||||
$description_str = shell_exec(("lspci -s ".$parts[0]));
|
||||
$description = preg_replace('/^\S+\s+/', '', $description_str);
|
||||
|
||||
$device = [
|
||||
'class' => trim($parts[1], '"'),
|
||||
'vendor_id' => trim($parts[2], '"'),
|
||||
'device_id' => trim($parts[3], '"'),
|
||||
'description' => trim($description,'"'),
|
||||
];
|
||||
|
||||
$devices[$parts[0]] = $device;
|
||||
$parts = explode(" ", $line);
|
||||
if (count($parts) < 6) continue; // Skip malformed lines
|
||||
$description_str = shell_exec(("lspci -s ".$parts[0]));
|
||||
$description = preg_replace('/^\S+\s+/', '', $description_str);
|
||||
$device = [
|
||||
'class' => trim($parts[1], '"'),
|
||||
'vendor_id' => trim($parts[2], '"'),
|
||||
'device_id' => trim($parts[3], '"'),
|
||||
'description' => trim($description,'"'),
|
||||
];
|
||||
$devices[$parts[0]] = $device;
|
||||
}
|
||||
}
|
||||
return $devices;
|
||||
@@ -514,61 +550,55 @@ function loadCurrentPCIData() {
|
||||
|
||||
// Compare the saved and current data
|
||||
function comparePCIData() {
|
||||
|
||||
$changes = [];
|
||||
$saved = loadSavedData("/boot/config/savedpcidata.json");
|
||||
if (!$saved) return [];
|
||||
$current = loadCurrentPCIData();
|
||||
|
||||
// Compare saved devices with current devices
|
||||
foreach ($saved as $pci_id => $saved_device) {
|
||||
if (!isset($current[$pci_id])) {
|
||||
// Device has been removed
|
||||
$changes[$pci_id] = [
|
||||
'status' => 'removed',
|
||||
'device' => $saved_device
|
||||
];
|
||||
} else {
|
||||
// Device exists in both, check for modifications
|
||||
$current_device = $current[$pci_id];
|
||||
$differences = [];
|
||||
|
||||
// Compare fields
|
||||
foreach (['vendor_id', 'device_id', 'class'] as $field) {
|
||||
if (isset($saved_device[$field]) && isset($current_device[$field]) && $saved_device[$field] !== $current_device[$field]) {
|
||||
$differences[$field] = [
|
||||
'old' => $saved_device[$field],
|
||||
'new' => $current_device[$field]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($differences)) {
|
||||
$changes[$pci_id] = [
|
||||
'status' => 'changed',
|
||||
'device' => $current_device,
|
||||
'differences' => $differences
|
||||
];
|
||||
}
|
||||
$changes = [];
|
||||
$saved = loadSavedData("/boot/config/savedpcidata.json");
|
||||
if (!$saved) return [];
|
||||
$current = loadCurrentPCIData();
|
||||
// Compare saved devices with current devices
|
||||
foreach ($saved as $pci_id => $saved_device) {
|
||||
if (!isset($current[$pci_id])) {
|
||||
// Device has been removed
|
||||
$changes[$pci_id] = [
|
||||
'status' => 'removed',
|
||||
'device' => $saved_device
|
||||
];
|
||||
} else {
|
||||
// Device exists in both, check for modifications
|
||||
$current_device = $current[$pci_id];
|
||||
$differences = [];
|
||||
// Compare fields
|
||||
foreach (['vendor_id', 'device_id', 'class'] as $field) {
|
||||
if (isset($saved_device[$field]) && isset($current_device[$field]) && $saved_device[$field] !== $current_device[$field]) {
|
||||
$differences[$field] = [
|
||||
'old' => $saved_device[$field],
|
||||
'new' => $current_device[$field]
|
||||
];
|
||||
}
|
||||
}
|
||||
if (!empty($differences)) {
|
||||
$changes[$pci_id] = [
|
||||
'status' => 'changed',
|
||||
'device' => $current_device,
|
||||
'differences' => $differences
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Check for added devices
|
||||
foreach ($current as $pci_id => $current_device) {
|
||||
if (!isset($saved[$pci_id])) {
|
||||
// Device has been added
|
||||
$changes[$pci_id] = [
|
||||
'status' => 'added',
|
||||
'device' => $current_device
|
||||
];
|
||||
}
|
||||
}
|
||||
// Check for added devices
|
||||
foreach ($current as $pci_id => $current_device) {
|
||||
if (!isset($saved[$pci_id])) {
|
||||
// Device has been added
|
||||
$changes[$pci_id] = [
|
||||
'status' => 'added',
|
||||
'device' => $current_device
|
||||
];
|
||||
}
|
||||
return $changes;
|
||||
}
|
||||
return $changes;
|
||||
}
|
||||
|
||||
function clone_list($disk) {
|
||||
global $pools;
|
||||
return strpos($disk['status'],'_NP')===false && ($disk['type']=='Data' || in_array($disk['name'],$pools));
|
||||
return strpos($disk['status'],'_NP') === false && ($disk['type'] == 'Data' || in_array($disk['name'], $pools));
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
/* Copyright 2005-2025, Lime Technology
|
||||
* Copyright 2012-2025, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -11,21 +11,15 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$var = parse_ini_file('/var/local/emhttp/var.ini');
|
||||
$ini = '/var/local/emhttp/keyfile.ini';
|
||||
$tmp = '/var/tmp/missing.tmp';
|
||||
$var = parse_ini_file('/var/local/emhttp/var.ini');
|
||||
$luks = $var['luksKeyfile'];
|
||||
$text = $_POST['text'] ?? false;
|
||||
$file = $_POST['file'] ?? false;
|
||||
|
||||
if ($text) {
|
||||
file_put_contents($luks, $text);
|
||||
} elseif ($file) {
|
||||
file_put_contents($luks, base64_decode(preg_replace('/^data:.*;base64,/','',$file)));
|
||||
@unlink($tmp);
|
||||
} elseif (file_exists($luks)) {
|
||||
if ($file) {
|
||||
file_put_contents($luks, base64_decode(explode(';base64,',$file)[1]));
|
||||
} elseif ($text && file_exists($luks)) {
|
||||
unlink($luks);
|
||||
touch($tmp);
|
||||
}
|
||||
$save = false;
|
||||
?>
|
||||
|
||||
@@ -25,8 +25,7 @@ $_arrow_ = '»';
|
||||
function file_put_contents_atomic($filename,$data) {
|
||||
while (true) {
|
||||
$suffix = rand();
|
||||
if ( ! is_file("$filename$suffix") )
|
||||
break;
|
||||
if (!is_file("$filename$suffix")) break;
|
||||
}
|
||||
$renResult = false;
|
||||
$writeResult = @file_put_contents("$filename$suffix",$data) === strlen($data);
|
||||
@@ -217,7 +216,7 @@ function my_logger($message, $logger='webgui') {
|
||||
* @param ?array $getinfo Empty array passed by reference, will contain results of curl_getinfo and curl_error, or null if not needed
|
||||
* @return string|false $out The fetched content
|
||||
*/
|
||||
function http_get_contents(string $url, array $opts = [], ?array &$getinfo = NULL) {
|
||||
function http_get_contents(string $url, array $opts=[], ?array &$getinfo=NULL) {
|
||||
$ch = curl_init();
|
||||
if(isset($getinfo)) {
|
||||
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
|
||||
@@ -272,4 +271,8 @@ function lan_port($port, $state=false) {
|
||||
$exist = file_exists("$system/$port");
|
||||
return !$state ? $exist : ($exist ? (@file_get_contents("$system/$port/carrier") ?: 0) : false);
|
||||
}
|
||||
|
||||
function shieldarg(...$args) {
|
||||
return implode(' ', array_map('escapeshellarg', $args));
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
/* Copyright 2005-2025, Lime Technology
|
||||
* Copyright 2012-2025, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -22,63 +22,65 @@ $save = false;
|
||||
$disks = parse_ini_file('state/disks.ini',true);
|
||||
$newkey = parse_ini_file('state/var.ini')['luksKeyfile'] ?: '/root/keyfile';
|
||||
$oldkey = dirname($newkey).'/oldfile';
|
||||
$delkey = !is_file($newkey);
|
||||
$crypto = [];
|
||||
|
||||
foreach (glob('/dev/disk/by-id/*CRYPT-LUKS*',GLOB_NOSORT) as $disk) {
|
||||
foreach (glob('/dev/disk/by-id/*CRYPT-LUKS*', GLOB_NOSORT) as $disk) {
|
||||
$disk = explode('-',$disk);
|
||||
$crypto[] = array_pop($disk);
|
||||
}
|
||||
if (count($crypto)==0) die();
|
||||
if (count($crypto) == 0) reply(_('No encrypted disks found'),'warning');
|
||||
|
||||
function delete_file(...$file) {
|
||||
array_map('unlink',array_filter($file,'is_file'));
|
||||
array_map('unlink', array_filter($file,'is_file'));
|
||||
}
|
||||
function removeKey($key,$disk) {
|
||||
|
||||
function removeKey($key, $disk) {
|
||||
$match = $slots = 0;
|
||||
$dump = popen("cryptsetup luksDump /dev/$disk",'r');
|
||||
while (($row = fgets($dump))!==false) {
|
||||
if (strncmp($row,'Version:',8)==0) {
|
||||
switch (trim(explode(':',$row)[1])) {
|
||||
$dump = popen("cryptsetup luksDump ".escapeshellarg("/dev/$disk"), 'r');
|
||||
while (($row = fgets($dump)) !== false) {
|
||||
if (strncmp($row,'Version:',8) == 0) {
|
||||
switch (trim(explode(':', $row)[1])) {
|
||||
case 1: $match = '/^Key Slot \d+: ENABLED$/'; break;
|
||||
case 2: $match = '/^\s+\d+: luks2$/'; break;
|
||||
}
|
||||
}
|
||||
if ($match && preg_match($match,$row)) $slots++;
|
||||
if ($match && preg_match($match, $row)) $slots++;
|
||||
}
|
||||
pclose($dump);
|
||||
if ($slots > 1) exec("cryptsetup luksRemoveKey /dev/$disk $key &>/dev/null");
|
||||
if ($slots > 1) exec("cryptsetup luksRemoveKey ".shieldarg("/dev/$disk", $key)." &>/dev/null");
|
||||
}
|
||||
|
||||
function diskname($name) {
|
||||
global $disks;
|
||||
foreach ($disks as $disk) if (strncmp($name,$disk['device'],strlen($disk['device']))==0) return $disk['name'];
|
||||
foreach ($disks as $disk) if (strncmp($name, $disk['device'], strlen($disk['device'])) == 0) return $disk['name'];
|
||||
return $name;
|
||||
}
|
||||
function reply($text,$type) {
|
||||
global $oldkey,$newkey,$delkey;
|
||||
|
||||
function reply($text, $type) {
|
||||
global $oldkey, $newkey;
|
||||
$reply = _var($_POST,'#reply');
|
||||
if (realpath(dirname($reply))=='/var/tmp') file_put_contents($reply,$text."\0".$type);
|
||||
if (realpath(dirname($reply)) == '/var/tmp') file_put_contents($reply, $text."\0".$type);
|
||||
delete_file($oldkey);
|
||||
if (_var($_POST,'newinput','text')=='text' || $delkey) delete_file($newkey);
|
||||
if (_var($_POST,'newinput','text') == 'text') delete_file($newkey);
|
||||
die();
|
||||
}
|
||||
|
||||
if (isset($_POST['oldinput'])) {
|
||||
switch ($_POST['oldinput']) {
|
||||
case 'text':
|
||||
file_put_contents($oldkey,base64_decode(_var($_POST,'oldluks')));
|
||||
file_put_contents($oldkey, base64_decode(_var($_POST,'oldluks')));
|
||||
break;
|
||||
case 'file':
|
||||
file_put_contents($oldkey,base64_decode(explode(';base64,',_var($_POST,'olddata','x;base64,'))[1]));
|
||||
file_put_contents($oldkey, base64_decode(explode(';base64,',_var($_POST,'olddata','x;base64,'))[1]));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (is_file($newkey)) copy($newkey,$oldkey);
|
||||
if (is_file($newkey)) copy($newkey, $oldkey);
|
||||
}
|
||||
|
||||
if (is_file($oldkey)) {
|
||||
$disk = $crypto[0]; // check first disk only (key is the same for all disks)
|
||||
exec("cryptsetup luksOpen --test-passphrase --key-file $oldkey /dev/$disk &>/dev/null",$null,$error);
|
||||
exec("cryptsetup luksOpen --test-passphrase --key-file ".shieldarg($oldkey, "/dev/$disk")." &>/dev/null", $null, $error);
|
||||
} else $error = 1;
|
||||
|
||||
if ($error > 0) reply(_('Incorrect existing key'),'warning');
|
||||
@@ -86,25 +88,25 @@ if ($error > 0) reply(_('Incorrect existing key'),'warning');
|
||||
if (isset($_POST['newinput'])) {
|
||||
switch ($_POST['newinput']) {
|
||||
case 'text':
|
||||
file_put_contents($newkey,base64_decode(_var($_POST,'newluks')));
|
||||
file_put_contents($newkey, base64_decode(_var($_POST,'newluks')));
|
||||
$luks = 'luksKey';
|
||||
$data = _var($_POST,'newluks');
|
||||
$data = str_replace('+', '%2B', _var($_POST,'newluks'));
|
||||
break;
|
||||
case 'file':
|
||||
file_put_contents($newkey,base64_decode(explode(';base64,',_var($_POST,'newdata','x;base64,'))[1]));
|
||||
file_put_contents($newkey, base64_decode(explode(';base64,',_var($_POST,'newdata','x;base64,'))[1]));
|
||||
$luks = 'luksKey=&luksKeyfile';
|
||||
$data = $newkey;
|
||||
break;
|
||||
}
|
||||
$good = $bad = [];
|
||||
foreach ($crypto as $disk) {
|
||||
exec("cryptsetup luksAddKey --key-file $oldkey /dev/$disk $newkey &>/dev/null",$null,$error);
|
||||
if ($error==0) $good[] = $disk; else $bad[] = diskname($disk);
|
||||
exec("cryptsetup luksAddKey --key-file ".shieldarg($oldkey, "/dev/$disk", $newkey)." &>/dev/null", $null, $error);
|
||||
if ($error == 0) $good[] = $disk; else $bad[] = diskname($disk);
|
||||
}
|
||||
if (count($bad)==0) {
|
||||
if (count($bad) == 0) {
|
||||
// all okay, remove the old key
|
||||
foreach ($good as $disk) removeKey($oldkey,$disk);
|
||||
exec("emcmd 'changeDisk=apply&$luks=$data'");
|
||||
foreach ($good as $disk) removeKey($oldkey, $disk);
|
||||
exec("emcmd ".escapeshellarg("changeDisk=apply&$luks=$data"));
|
||||
reply(_('Key successfully changed'),'success');
|
||||
} else {
|
||||
// something went wrong, restore key
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/php -q
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
/* Copyright 2005-2025, Lime Technology
|
||||
* Copyright 2012-2025, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -34,14 +34,17 @@ $locale_init = $locale;
|
||||
function initSum() {
|
||||
return ['count'=>0, 'temp'=>0, 'power'=>0, 'fsSize'=>0, 'fsUsed'=>0, 'fsFree'=>0, 'ioReads'=>0, 'ioWrites'=>0, 'numReads'=>0, 'numWrites'=>0, 'numErrors'=>0];
|
||||
}
|
||||
|
||||
function get_model($id) {
|
||||
return substr($id,0,strrpos($id,'_'));
|
||||
}
|
||||
|
||||
function my_power($power) {
|
||||
global $display;
|
||||
$number = _var($display,'number','.,');
|
||||
return _var($display,'power') && $power ? number_format($power,$power<10?2:1,$number[0]).' '._('W').' / ' : '';
|
||||
}
|
||||
|
||||
function device_info(&$disk,$online) {
|
||||
global $pools, $var;
|
||||
if (!$online || _var($disk,'fsStatus')!='Mounted' || (in_array(_var($disk,'type'),['Parity','Cache']) && (!in_array(_var($disk,'name'),$pools) || isSubpool(_var($disk,'name'))))) {
|
||||
@@ -84,6 +87,7 @@ function device_info(&$disk,$online) {
|
||||
: $fancy;
|
||||
return $view.$status.$link;
|
||||
}
|
||||
|
||||
function device_desc(&$disk) {
|
||||
global $var;
|
||||
$size = my_scale(_var($disk,'sectors',0)*_var($disk,'sector_size',0),$unit,-1);
|
||||
@@ -101,6 +105,7 @@ function device_desc(&$disk) {
|
||||
return my_id(_var($disk,'id'))." - $size $unit ("._var($disk,'device').")";
|
||||
}
|
||||
}
|
||||
|
||||
function assignment(&$disk) {
|
||||
global $var, $devs;
|
||||
$echo = [];
|
||||
@@ -119,18 +124,18 @@ function assignment(&$disk) {
|
||||
$echo[] = "</select></form>";
|
||||
return implode($echo);
|
||||
}
|
||||
|
||||
function vfs_luks($fs) {
|
||||
return str_starts_with($fs,'luks:');
|
||||
}
|
||||
|
||||
function vfs_type(&$disk,$online = false) {
|
||||
global $disks, $pools, $crypto;
|
||||
$fsType = _var($disk,'fsType','');
|
||||
$luks = '';
|
||||
if (empty($fsType))
|
||||
return $fsType;
|
||||
if ($crypto) switch (_var($disk,'luksState',0)) {
|
||||
if (empty($fsType)) return;
|
||||
if (vfs_luks($fsType) && $crypto) switch (_var($disk,'luksState',0)) {
|
||||
case 0:
|
||||
if (vfs_luks($fsType))
|
||||
$luks = "<a class='info'><i class='padlock fa fa-unlock-alt orange-text'></i><span>"._('Device to be encrypted')."</span></a>";
|
||||
break;
|
||||
case 1:
|
||||
@@ -151,6 +156,7 @@ function vfs_type(&$disk,$online = false) {
|
||||
}
|
||||
return $luks.str_replace('luks:','',$fsType);
|
||||
}
|
||||
|
||||
function fs_info(&$disk,$online = false) {
|
||||
global $display;
|
||||
$echo = [];
|
||||
@@ -176,9 +182,11 @@ function fs_info(&$disk,$online = false) {
|
||||
}
|
||||
return implode($echo);
|
||||
}
|
||||
|
||||
function my_diskio($data) {
|
||||
return my_scale($data,$unit,1)." $unit/s";
|
||||
}
|
||||
|
||||
function array_offline(&$disk, $pool='') {
|
||||
global $var, $disks, $display;
|
||||
$disk['power'] ??= (_var($display,'power') && _var($disk,'transport')=='nvme' ? get_nvme_info(_var($disk,'device'),'power') : 0);
|
||||
@@ -256,6 +264,7 @@ function array_offline(&$disk, $pool='') {
|
||||
$echo[] = "</tr>";
|
||||
return implode($echo);
|
||||
}
|
||||
|
||||
function array_online(&$disk, $fstype='') {
|
||||
global $pools, $sum, $diskio;
|
||||
$disk['power'] ??= (_var($disk,'transport')=='nvme' ? get_nvme_info(_var($disk,'device'),'power') : 0);
|
||||
@@ -310,6 +319,7 @@ function array_online(&$disk, $fstype='') {
|
||||
$echo[] = "</tr>";
|
||||
return implode($echo);
|
||||
}
|
||||
|
||||
function show_totals($text,$array,$name) {
|
||||
global $var, $display, $sum, $locale;
|
||||
$number = _var($display,'number','.,');
|
||||
@@ -346,6 +356,7 @@ function show_totals($text,$array,$name) {
|
||||
$echo[] = "</tr>";
|
||||
return implode($echo);
|
||||
}
|
||||
|
||||
function array_slots() {
|
||||
global $var;
|
||||
$min = max(_var($var,'sbNumDisks',0),3);
|
||||
@@ -364,6 +375,7 @@ function array_slots() {
|
||||
$echo[] = "</select></form>";
|
||||
return implode($echo);
|
||||
}
|
||||
|
||||
function cache_slots($off,$pool,$min,$slots) {
|
||||
global $var, $disks;
|
||||
// $off = $off && $min ? ' disabled' : '';
|
||||
@@ -386,6 +398,7 @@ function cache_slots($off,$pool,$min,$slots) {
|
||||
$echo[] = "</select></form>";
|
||||
return implode($echo);
|
||||
}
|
||||
|
||||
function update_translation($locale) {
|
||||
global $docroot,$language;
|
||||
$language = [];
|
||||
@@ -404,6 +417,7 @@ function update_translation($locale) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
$var = (array)@parse_ini_file("$varroot/var.ini");
|
||||
$devs = (array)@parse_ini_file("$varroot/devs.ini",true);
|
||||
|
||||
@@ -15,6 +15,14 @@ else
|
||||
log "no queued job present"
|
||||
fi
|
||||
|
||||
echo "sleep ${1:-1}; /usr/local/emhttp/webGui/scripts/reload_services" | at -M now 2>/dev/null
|
||||
log "queue new job $(queue), wait for ${1:-1}s"
|
||||
# Validate delay parameter is numeric
|
||||
if [[ -n $1 && ! $1 =~ ^[0-9]+$ ]]; then
|
||||
log "invalid delay parameter: $1, using default"
|
||||
DELAY=1
|
||||
else
|
||||
DELAY=${1:-1}
|
||||
fi
|
||||
|
||||
echo "sleep $DELAY; /usr/local/emhttp/webGui/scripts/reload_services" | at -M now 2>/dev/null
|
||||
log "queue new job $(queue), wait for ${DELAY}s"
|
||||
exit 0
|
||||
|
||||
@@ -16,7 +16,7 @@ nchan_idle(){
|
||||
idle=3
|
||||
for n in {1..3}; do
|
||||
subs=$(nchan_subs)
|
||||
[[ -z $subs || $subs =~ ^[0-9]+$ && $subs -eq 0 ]] && ((idle--))
|
||||
[[ -z $subs || ( $subs =~ ^[0-9]+$ && $subs -eq 0 ) ]] && ((idle--))
|
||||
sleep 3
|
||||
done
|
||||
[[ $idle -eq 0 ]]
|
||||
|
||||
Reference in New Issue
Block a user