mirror of
https://github.com/unraid/webgui.git
synced 2026-04-22 01:40:58 -05:00
Merge branch 'master' into master
This commit is contained in:
@@ -545,6 +545,9 @@ window.onunload = function(){
|
||||
<? 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"):?>
|
||||
<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"):?>
|
||||
<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>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Menu="Dashboard"
|
||||
Nchan="wg_poller,update_1,update_2,update_3,ups_status:stop"
|
||||
Nchan="wg_poller,update_1,update_2,update_3,ups_status:stop,vm_dashusage:stop"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology * Copyright 2012-2023, Bergware International.
|
||||
@@ -73,6 +73,10 @@ $vdisk = exec("grep -Pom1 '^DOCKER_IMAGE_TYPE=\"\\K[^\"]+' /boot/config/docker.c
|
||||
$dot = _var($display,'number','.,')[0];
|
||||
$zfs = count(array_filter(array_column($disks,'fsType'),function($fs){return str_replace('luks:','',$fs??'')=='zfs';}));
|
||||
|
||||
$domain_cfgfile = "/boot/config/domain.cfg";
|
||||
$domain_cfg = parse_ini_file($domain_cfgfile);
|
||||
if (!isset($domain_cfg['USAGE'])) $vmusage = "N" ; else $vmusage = $domain_cfg['USAGE'];
|
||||
|
||||
// enable/disable graph elements by making hook script executable or not
|
||||
chmod("$docroot/webGui/system/VM_usage",$libvirtd ? 0755 : 0644);
|
||||
chmod("$docroot/webGui/system/ZFS_cache",$zfs ? 0755 : 0644);
|
||||
@@ -275,10 +279,10 @@ foreach ($cpus as $pair) {
|
||||
<a href='/Dashboard/Tools/Processes' title="_(View Running Processes)_"><i class='fa fa-fw fa-info-circle control'></i></a>
|
||||
</td></tr><tr><td>
|
||||
<span class='w26'><i class='ups fa fa-compress'></i>_(Usable size)_: <?=$ramsize?><br><i class='ups fa fa-expand'></i>_(Maximum size)_: <?="$memory_maximum $unit"?><?=$low?'*':''?></span>
|
||||
<span class='w18 center'><a class='info hand none'>_(RAM usage)_<span>_(Percent of total used memory)_ (<?=$ramsize?>)</span></a></span>
|
||||
<span class='w18 center'><a class='info hand none'>_(Flash device)_<span>_(Percent usage of flash usb device)_ (<?=$flashsize?>)</span></a></span>
|
||||
<span class='w18 center'><a class='info hand none'>_(Log filesystem)_<span>_(Percent usage of LOG file system)_ (<?=$logsize?>)</span></a></span>
|
||||
<span class='w18 center'><a class='info hand none'><?=$vdisk?><span><?=_("Percent usage of $vdisk")?> (<?=$dockersize?>)</span></a></span>
|
||||
<span class='w18 center static'><a class='info hand none'>_(RAM usage)_<span>_(Percent of total used memory)_ (<?=$ramsize?>)</span></a></span>
|
||||
<span class='w18 center static'><a class='info hand none'>_(Flash device)_<span>_(Percent usage of flash usb device)_ (<?=$flashsize?>)</span></a></span>
|
||||
<span class='w18 center static'><a class='info hand none'>_(Log filesystem)_<span>_(Percent usage of LOG file system)_ (<?=$logsize?>)</span></a></span>
|
||||
<span class='w18 center static'><a class='info hand none'><?=$vdisk?><span><?=_("Percent usage of $vdisk")?> (<?=$dockersize?>)</span></a></span>
|
||||
</td></tr><tr><td>
|
||||
<span class='w26'><legend>_(Legend)_</legend><span id='dynamic'></span></span>
|
||||
<span class='w18 center'><div class='pie' id='sys0'><span class='sys0'></span><span class='var0'></span></div></span>
|
||||
@@ -424,6 +428,13 @@ echo "</td></tr>";
|
||||
<a href='/Dashboard/Settings/VMSettings' title="_(Go to VM settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
</td></tr>
|
||||
</tbody>
|
||||
<?if ($vmusage == "Y"):?>
|
||||
<tbody id='vm_view_usage' title="_(Virtual Machines Usage)_" >
|
||||
<tr><td><i class='icon-virtualization f32'></i><div class='section'>_(Virtual Machines Usage)_</div>
|
||||
<a href='/Dashboard/Settings/VMSettings' title="_(Go to VM settings)_"><i class='fa fa-fw fa-cog control'></i></a>
|
||||
</td></tr>
|
||||
</tbody>
|
||||
<?endif;?>
|
||||
<?endif;?>
|
||||
|
||||
<tbody title="_(Shares Information)_"<?if ($group):?> class="mixed"<?endif;?>>
|
||||
@@ -685,7 +696,8 @@ function hideShow() {
|
||||
<tr><td>_(VM Name)_:</td><td><label id="VMName"></label></td></tr>
|
||||
<tr><td>_(Snapshot Name)_:</td><td><input type="text" id="targetsnap" autocomplete="off" spellcheck="false" value="--generate" onclick="this.select()">_(Check free space)_:<input type="checkbox" id="targetsnapfspc" checked></td></tr>
|
||||
<tr><td>_(Description)_:</td><td><input type="text" id="targetsnapdesc" autocomplete="off" spellcheck="false" value="" onclick="this.select()"></td></tr>
|
||||
<tr id="fstypeline"><td>_(FS Native Snapshot )_:</td><td><label id="fstype"></label><input type="checkbox" id="targetsnapfstype" checked>_(Unchecked will use QEMU External Snapshot)_</td></tr>
|
||||
<tr id="memoryline"><td>_(Memory dump )_:</td><td><input type="checkbox" id="targetsnapmem" checked></td></tr>
|
||||
<tr id="fstypeline"><td>_(FS Native Snapshot )_:</td><td><label id="fstype"></label><input type="checkbox" id="targetsnapfstype" >_(Unchecked will use QEMU External Snapshot)_</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -932,7 +944,7 @@ function loadlist(init) {
|
||||
$('#vms').is(':checked') ? $.cookie('my_vms','startedOnly',{expires:3650}) : $.removeCookie('my_vms');
|
||||
});
|
||||
}
|
||||
$.post('/webGui/include/DashboardApps.php',{docker:'<?=$dockerd?>',vms:'<?=$libvirtd?>'},function(d) {
|
||||
$.post('/webGui/include/DashboardApps.php',{docker:'<?=$dockerd?>',vms:'<?=$libvirtd?>',vmusage:'<?=$vmusage?>'},function(d) {
|
||||
var data = d.split('\0');
|
||||
$('#docker_view tr.updated').remove();
|
||||
$('#docker_view').append(data[0]).hideMe();
|
||||
@@ -944,6 +956,8 @@ function loadlist(init) {
|
||||
var started_vms = $('#vm_view').find('span.outer.vms.started').length;
|
||||
var stopped_vms = $('#vm_view').find('span.outer.vms.stopped').length;
|
||||
var paused_vms = $('#vm_view').find('span.outer.vms.paused').length;
|
||||
$('#vm_view_usage tr.useupdated').remove();
|
||||
$('#vm_view_usage').append(data[2]).hideMe();
|
||||
$('.apps.switch').html("_(Containers)_ -- _(Started)_: "+started_apps+", _(Stopped)_: "+stopped_apps+", _(Paused)_: "+paused_apps);
|
||||
$('.vms.switch').html("_(VMs)_ -- _(Started)_: "+started_vms+", _(Stopped)_: "+stopped_vms+", _(Paused)_: "+paused_vms);
|
||||
if ($.cookie('my_apps')!=null) $('span.apps.stopped').hide(0,noApps());
|
||||
@@ -1209,7 +1223,7 @@ function addProperties() {
|
||||
$('div#sys3').hover(function(){$('.sys3').hide();$('.var3').show();},function(){$('.sys3').show();$('.var3').hide();});
|
||||
$('#current_time').hover(function(){$.post('/webGui/include/DashboardApps.php',{ntp:'ntp'},function(ntp){$('#current_time').prop('title',ntp+"\n_(Go to date and time settings)_");});});
|
||||
// make truncated descriptions fully visible when hovering over them
|
||||
$('span.w18').hover(
|
||||
$('span.w18').not('.static').hover(
|
||||
function(){if ($(this)[0].offsetWidth < $(this)[0].scrollWidth) {recall = $(this).next(); recover=recall.html(); recall.html(' ');}},
|
||||
function(){if ($(this)[0].offsetWidth < $(this)[0].scrollWidth) {recall.html(recover); recall=null;}}
|
||||
);
|
||||
@@ -1380,7 +1394,7 @@ function VMClone(uuid, name){
|
||||
});
|
||||
dialogStyle();
|
||||
}
|
||||
function selectsnapshot(uuid, name ,snaps, opt, getlist, status,fstype){
|
||||
function selectsnapshot(uuid, name ,snaps, opt, getlist, state,fstype){
|
||||
box = $("#iframe-popup");
|
||||
box.html($("#templatesnapshot"+opt).html());
|
||||
const capopt = opt.charAt(0).toUpperCase() + opt.slice(1);
|
||||
@@ -1394,7 +1408,21 @@ function selectsnapshot(uuid, name ,snaps, opt, getlist, status,fstype){
|
||||
var only = (opt == "remove") ? 0 : 1;
|
||||
$.post("/plugins/dynamix.vm.manager/include/VMajax.php",{action:"snap-images",uuid:uuid,snapshotname:snaps,only:only},function(data){if (data.html) box.find('#targetsnapimages').html(data.html);},'json');
|
||||
}
|
||||
var memorydump = "no";
|
||||
document.getElementById("targetsnapfspc").checked = true;
|
||||
if (fstype == "ZFS") {
|
||||
box.find('#targetsnaprmv').prop('disabled',true);
|
||||
box.find('#targetsnaprmvmeta').prop('disabled',true);
|
||||
}
|
||||
if (state != "running") {
|
||||
box.find('#memoryline').prop('hidden',true);
|
||||
box.find('#targetsnapmem').prop('hidden',true);
|
||||
box.find('#targetsnapmem').prop('checked',false);
|
||||
} else {
|
||||
box.find('#memoryline').prop('hidden',false);
|
||||
box.find('#targetsnapmem').prop('hidden',false);
|
||||
box.find('#targetsnapmem').prop('checked',true);
|
||||
}
|
||||
box.dialog({
|
||||
title: optiontext,
|
||||
height: 'auto',
|
||||
@@ -1422,10 +1450,11 @@ function selectsnapshot(uuid, name ,snaps, opt, getlist, status,fstype){
|
||||
if (opt == "create") {
|
||||
free = box.find('#targetsnapfspc').prop('checked') ? 'yes' : 'no';
|
||||
desc = box.find("#targetsnapdesc").prop('value');
|
||||
memorydump = box.find('#targetsnapmem').prop('checked') ? 'yes' : 'no';
|
||||
fstypeuse = box.find('#targetsnapfstype').prop('checked') ? 'yes' : 'no';
|
||||
if (fstypeuse == "no") fstype ="QEMU";
|
||||
}
|
||||
ajaxVMDispatch({action:"snap-" + opt +'-external', uuid:uuid, snapshotname:target, remove:remove, free:free, desc:desc, fstype:fstype}, "loadlist");
|
||||
ajaxVMDispatch({action:"snap-" + opt +'-external', uuid:uuid, snapshotname:target, remove:remove, free:free, desc:desc, fstype:fstype,memorydump:memorydump}, "loadlist");
|
||||
box.dialog('close');
|
||||
},
|
||||
"_(Cancel)_": function(){
|
||||
@@ -1501,6 +1530,18 @@ function cpu_parse(msg) {
|
||||
return parse;
|
||||
}
|
||||
|
||||
<?if ($vmusage == "Y"):?>
|
||||
var vmdashusage = new NchanSubscriber('/sub/vm_dashusage',{subscriber:'websocket'});
|
||||
vmdashusage.on('message', function(msg){
|
||||
var data = JSON.parse(msg);
|
||||
for (const [vm, vmdata] of Object.entries(data)) {
|
||||
for (const [displayitem, value] of Object.entries(vmdata)) {
|
||||
$('#vmmetrics-'+displayitem + '-' + vm ).html(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
<?endif;?>
|
||||
|
||||
var dashboard = new NchanSubscriber('/sub/cpuload,update1,update2,update3<?=$wireguard?",wireguard":""?>',{subscriber:'websocket'});
|
||||
dashboard.on('message',function(msg,meta) {
|
||||
switch (meta.id.channel()) {
|
||||
@@ -1667,6 +1708,9 @@ $(function() {
|
||||
dropdown('enter_view');
|
||||
startup = false;
|
||||
dashboard.start();
|
||||
<?if ($vmusage == "Y"):?>
|
||||
vmdashusage.start();
|
||||
<?endif;?>
|
||||
<?if ($apcupsd):?>
|
||||
apcups.start();
|
||||
<?endif;?>
|
||||
@@ -1692,6 +1736,9 @@ $(function() {
|
||||
|
||||
window.onunload = function(){
|
||||
dashboard.stop();
|
||||
<?if ($vmusage == "Y"):?>
|
||||
vmdashusage.stop();
|
||||
<?endif;?>
|
||||
<?if ($apcupsd):?>
|
||||
apcups.stop();
|
||||
<?endif;?>
|
||||
|
||||
@@ -313,7 +313,14 @@ function setGlue(form,reset) {
|
||||
{glue:'/',more:3,dev:1,type:'',min1:1,max1:4,min2:1,max2:128,min3:1,max3:4}, // highpoint
|
||||
{glue:'' ,more:1,dev:1,type:'',min1:0,max1:15}, // hp cciss
|
||||
{glue:'' ,more:0,dev:0,type:''}, // marvell
|
||||
{glue:',',more:1,dev:1,type:'',min1:0,max1:127} // megaraid
|
||||
{glue:',',more:1,dev:1,type:'',min1:0,max1:127}, // megaraid
|
||||
{glue:',',more:1,dev:0,type:'input',min1:'',max1:'0xffffffff'}, // cypress
|
||||
{glue:',',more:3,dev:0,type:'select',min1:'',max1:'p',min2:'',max2:'x',min3:1,max3:128},// jmicron ata
|
||||
{glue:'' ,more:0,dev:0,type:''}, // prolific
|
||||
{glue:'' ,more:0,dev:0,type:''}, // sunplus
|
||||
{glue:'' ,more:0,dev:0,type:''}, // asmedia
|
||||
{glue:'' ,more:0,dev:0,type:''}, // jmicron nvme
|
||||
{glue:'' ,more:0,dev:0,type:''}, // realtek
|
||||
];
|
||||
var n = form.smType.selectedIndex>0 ? form.smType.selectedIndex-1 : <?=_var($var,'smIndex',0)?>;
|
||||
var x = data[n]['more'];
|
||||
@@ -603,7 +610,7 @@ _(Spin down delay)_:
|
||||
_(File system status)_:
|
||||
: <?=_(_var($disk,'fsStatus'))?>
|
||||
|
||||
<?$disabled = (_var($var,'fsState')=="Stopped" && !empty(_var($disk,'uuid'))) || (_var($var,'fsState')=="Started" && _var($disk,'fsStatus')=='Mounted') ? "disabled" : ""?>
|
||||
<?$disabled = (_var($var,'fsState')=="Stopped" && !empty(_var($disk,'uuid'))) || (_var($var,'fsState')=="Started" && _var($disk,'fsType')!='auto') ? "disabled" : ""?>
|
||||
<?if (diskType('Data') || (!isSubpool($name) && _var($disk,'slots',0)==1)):?>
|
||||
_(File system type)_:
|
||||
: <select id="diskFsType" name="diskFsType.<?=_var($disk,'idx',0)?>" onchange="changeFsType()" <?=$disabled?>>
|
||||
@@ -1246,6 +1253,13 @@ _(SMART controller type)_:
|
||||
<?=mk_option(_var($disk,'smType'), "-d cciss", "HP cciss")?>
|
||||
<?=mk_option(_var($disk,'smType'), "-d marvell", "Marvell")?>
|
||||
<?=mk_option(_var($disk,'smType'), "-d megaraid", "MegaRAID")?>
|
||||
<?=mk_option(_var($disk,'smType'), "-d usbcypress", "Cypress ATACB")?>
|
||||
<?=mk_option(_var($disk,'smType'), "-d usbjmicron", "JMicron ATA pass-through")?>
|
||||
<?=mk_option(_var($disk,'smType'), "-d usbprolific", "Prolific ATA pass-through")?>
|
||||
<?=mk_option(_var($disk,'smType'), "-d usbsunplus", "Sunplus ATA pass-through")?>
|
||||
<?=mk_option(_var($disk,'smType'), "-d sntasmedia", "ASMedia NVMe pass-through")?>
|
||||
<?=mk_option(_var($disk,'smType'), "-d sntjmicron", "JMicron NVMe pass-through")?>
|
||||
<?=mk_option(_var($disk,'smType'), "-d sntrealtek", "Realtek NVMe pass-through")?>
|
||||
</select>
|
||||
<input type="text" name="smPort1" value="<?=_var($disk,'smPort1')?>" class="option"><select name="smPort1" class="narrow option" disabled></select>
|
||||
<input type="text" name="smPort2" value="<?=_var($disk,'smPort2')?>" class="option"><select name="smPort2" class="narrow option" disabled></select>
|
||||
|
||||
@@ -364,6 +364,13 @@ _(Default SMART controller type)_:
|
||||
<?=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")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d usbcypress", "Cypress ATACB")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d usbjmicron", "JMicron ATA pass-through")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d usbprolific", "Prolific ATA pass-through")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d usbsunplus", "Sunplus ATA pass-through")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d sntasmedia", "ASMedia NVMe pass-through")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d sntjmicron", "JMicron NVMe pass-through")?>
|
||||
<?=mk_option(_var($var,'smType'), "-d sntrealtek", "Realtek NVMe pass-through")?>
|
||||
</select>
|
||||
|
||||
:disk_default_smart_controller_help:
|
||||
|
||||
@@ -5,8 +5,8 @@ Icon="icon-key"
|
||||
Tag="expeditedssl"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
/* Copyright 2005-2024, Lime Technology
|
||||
* Copyright 2012-2024, 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,
|
||||
@@ -75,7 +75,7 @@ if ($cert1Present) {
|
||||
$cert1SelfSigned = ($cert1Subject == $cert1Issuer);
|
||||
}
|
||||
|
||||
// unraid.net, myunraid.net LE cert. could potentially be user provided as well
|
||||
// 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) {
|
||||
@@ -84,6 +84,8 @@ if ($cert2Present) {
|
||||
$cert2Expires = exec("/usr/bin/openssl x509 -in $cert2File -noout -text | sed -n -e 's/^.*Not After : //p'");
|
||||
$isWildcardCert = preg_match('/.*\.myunraid\.net$/', $cert2Subject);
|
||||
$subject2URL = $cert2Subject;
|
||||
$dnsValid = false;
|
||||
$dnsRebindingProtection = false;
|
||||
if ($isWildcardCert) {
|
||||
exec("openssl x509 -checkend 2592000 -noout -in $cert2File 2>/dev/null", $arrout, $retval_expired);
|
||||
if (!$addr) {
|
||||
@@ -119,8 +121,8 @@ $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_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}/";
|
||||
@@ -164,7 +166,6 @@ $cert_time_format = $display['date'].($display['date']!='%c' ? ', '.str_replac
|
||||
$provisionlabel = $isWildcardCert ? _('Renew') : _('Provision');
|
||||
$disabled_provision = $keyfile===false || ($isWildcardCert && $retval_expired===0) || !$addr ? 'disabled' : '';
|
||||
$disabled_provision_msg = !$addr ? _('Ensure the primary network card eth0 has an IP address.') : '';
|
||||
$disabled_updatedns = $keyfile!==false && $isWildcardCert ? '' : 'disabled';
|
||||
$disabled_delete = $cert2Present && $var['USE_SSL']!='auto' ? '' : 'disabled';
|
||||
$disabled_auto = $isWildcardCert && !$dnsRebindingProtection && $dnsValid ? '' : 'disabled';
|
||||
|
||||
@@ -189,23 +190,6 @@ function provisionHandler(event, form) { // provisions and renewals require bein
|
||||
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 = [];
|
||||
@@ -359,12 +343,10 @@ _(Local access URLs)_:
|
||||
$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[1]) $msg .= " "._("redirects to")." <a href='$url[1]'>$url[1]</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>" : "");
|
||||
echo ($n ? "<dt> </dt><dd>" : ""),"<a href='$url[0]'>$url[0]</a>$msg",($n++ ? "</dd>" : "");
|
||||
}?>
|
||||
|
||||
:mgmt_local_access_urls_help:
|
||||
@@ -431,7 +413,7 @@ _(CA-signed certificate file)_:
|
||||
|
||||
<?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?>
|
||||
: <button type="submit" name="changePorts" value="Provision" <?=$disabled_provision?>><?=$provisionlabel?></button><button type="submit" name="changePorts" value="Delete" <?=$disabled_delete?> >_(Delete)_</button><?=$disabled_provision_msg?>
|
||||
|
||||
:mgmt_certificate_expiration_help:
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@ Tag="folder-o"
|
||||
<?
|
||||
$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';
|
||||
return in_array(_var($disk,'type'),['Data','Cache']) && array_key_exists('exportable',$disk) && _var($disk,'fsStatus')=='Mounted';
|
||||
}
|
||||
?>
|
||||
<script>
|
||||
|
||||
@@ -101,7 +101,7 @@ function textsave(module,remove = false) {
|
||||
if (data.modprobe == "") $('#text'+module).attr('hidden', true); else $('#text'+module).attr('rows', 3);
|
||||
if (data.supportpage == true) {
|
||||
if (data.support == true) {
|
||||
document.getElementById("link" + module).innerHTML = "<a href='" + data.supporturl + "'target='_blank'><i title='"+_("Support page")_+"' class='fa fa-phone-square'></i></a>";
|
||||
document.getElementById("link" + module).innerHTML = "<a href='" + data.supporturl + "'target='_blank'><i title='"+"_(Support page)_"+"' class='fa fa-phone-square'></i></a>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,15 @@ _(Local syslog folder)_:
|
||||
|
||||
:syslog_local_folder_help:
|
||||
|
||||
_(System identifier for logfile name)_:
|
||||
: <select name="server_filename">
|
||||
<?=mk_option($syslog['server_filename'], "syslog-%FROMHOST-IP%.log", _("IP Address"))?>
|
||||
<?=mk_option($syslog['server_filename'], "syslog-%HOSTNAME%.log", _("Hostname (from syslog message)"))?>
|
||||
<?=mk_option($syslog['server_filename'], "syslog-%FROMHOST%.log", _("Hostname (from DNS reverse lookup)"))?>
|
||||
</select>
|
||||
|
||||
:syslog_remote_system_identifier_help:
|
||||
|
||||
_(Local syslog rotation)_:
|
||||
: <select name="log_rotation" onchange="logOptions(this.value,'slow')">
|
||||
<?=mk_option(_var($syslog,'log_rotation'), "", _("Disabled"))?>
|
||||
@@ -146,7 +155,7 @@ _(Local syslog number of files)_:
|
||||
</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>
|
||||
: <span class="span"><input type="text" name="remote_server" class="narrow" value="<?=_var($syslog,'remote_server')?>" maxlength="50" placeholder="_(name or ip address)_"></span>
|
||||
<select name="remote_protocol" class="narrow">
|
||||
<?=mk_option(_var($syslog,'remote_protocol'), "udp", _("UDP"))?>
|
||||
<?=mk_option(_var($syslog,'remote_protocol'), "tcp", _("TCP"))?>
|
||||
|
||||
@@ -30,6 +30,8 @@ $(function() {
|
||||
$globals = [];
|
||||
$names = ['_SERVER','devs','disks','sec','sec_nfs','shares','users','var'];
|
||||
foreach ($names as $name) $globals[$name] = $$name;
|
||||
// show outgoing proxy information, is in the environment but not a superglobal
|
||||
$globals['environment'] = ['http_proxy' => getenv('http_proxy'), 'no_proxy' => getenv('no_proxy')];
|
||||
echo "<pre class='up'>",htmlspecialchars(print_r($globals,true)),"</pre>";
|
||||
?>
|
||||
<input type="button" value="_(Done)_" onclick="done()">
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
Menu="UNRAID-OS"
|
||||
Title="Wake On LAN"
|
||||
Icon="fa-bell"
|
||||
Tag="server"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
if (count($_POST)) {
|
||||
$cfg = NULL ;
|
||||
if ($_POST['#apply'] == "_(Save)_") {
|
||||
foreach($_POST as $postkey=>$data) {
|
||||
if ($postkey=="#apply") continue;
|
||||
$keys = explode(";",$postkey);
|
||||
if (count($keys) >1) $update_file[$keys[1]][$keys[2]][$keys[0]]=$data;
|
||||
}
|
||||
|
||||
foreach($update_file as $type => $types) {
|
||||
foreach($types as $name => $details) {
|
||||
if ($details['user_mac'] == "") $details['user_mac'] = "None Defined";
|
||||
if ($details['user_mac'] == "None Defined" && ($details['enable'] == "enable" || $details['enable'] == "shutdown")) unset($update_file[$type][$name]) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($_POST) ;
|
||||
file_put_contents("/boot/config/wol.json",json_encode($update_file));
|
||||
#echo '<meta http-equiv="refresh" content="0;url=/Tools">';
|
||||
echo '<meta http-equiv="refresh" content="0">';
|
||||
#unset($_SESSION['csrf_token']);
|
||||
|
||||
|
||||
|
||||
}
|
||||
?>
|
||||
<script src="/webGui/javascript/jquery.tablesorter.widgets.js"></script>
|
||||
|
||||
<script>
|
||||
function showWOL(options, init = false) {
|
||||
option = options;
|
||||
if (init) {
|
||||
$('#wolsearch').prop('disabled', true);
|
||||
$.post('/webGui/include/WOL.php',{table:'t1load',option:"all"},function(data){
|
||||
clearTimeout(timers.refresh);
|
||||
filter = [];
|
||||
$("#t1").trigger("destroy");
|
||||
$('#t1').html(data.html);
|
||||
$('#t1').tablesorter({
|
||||
sortList: [[0,0]],
|
||||
sortAppend: [[0,0]],
|
||||
widgets: ['stickyHeaders','filter','zebra'],
|
||||
widgetOptions: {
|
||||
// on black and white, offset is height of #menu
|
||||
// on azure and gray, offset is height of #header
|
||||
stickyHeaders_offset: ($('#menu').height() < 50) ? $('#menu').height() : $('#header').height(),
|
||||
filter_columnFilters: false,
|
||||
zebra: ["normal-row","alt-row"]
|
||||
}
|
||||
});
|
||||
$('div.spinner.fixed').hide('slow');
|
||||
$('#wolsearch').prop('disabled', false);
|
||||
$('#select').prop('disabled', false);
|
||||
$('#rebuild').prop('disabled', data.init);
|
||||
},"json");
|
||||
} else {
|
||||
filter = [];
|
||||
filterWOL();
|
||||
}
|
||||
}
|
||||
|
||||
function filterWOL() {
|
||||
var totalColumns = $('#t1')[0].config.columns;
|
||||
var filter = [];
|
||||
filter[totalColumns] = $('#wolsearch').val(); // this searches all columns
|
||||
$('#t1').trigger('search', [filter]);
|
||||
}
|
||||
|
||||
function showWOLupdate() {
|
||||
$('#rebuild').prop('disabled', true);
|
||||
$('#t1').html("");
|
||||
$('#wolsearch').prop('disabled', true);
|
||||
$('#select').prop('disabled', true);
|
||||
$('div.spinner.fixed').show('slow');
|
||||
$.post('/webGui/include/WOL.php',{table:'t1create',option:"all"},function(data){
|
||||
$('#rebuild').prop('disabled', false);
|
||||
showWOL("all",true);
|
||||
$('div.spinner.fixed').hide('slow');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function maccreate(name) {
|
||||
|
||||
$.post('/webGui/include/WOL.php',{table:'macaddress'}, function( data ) {
|
||||
if (data.mac) {
|
||||
$('#'+name).val(data.mac);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
showWOL("all",true);
|
||||
</script>
|
||||
|
||||
:WOL_intro_help:
|
||||
|
||||
<form autocomplete="off" onsubmit="return false;"><span><input class="t1 search" id="wolsearch" type="search" placeholder="Search..." onchange="filterWOL();"></span></form>
|
||||
<pre><form name="WOL" id="WOL" method="POST" class="js-confirm-leave" >
|
||||
<table name="t1"id='t1' class="t1 unraid tablesorter" >
|
||||
<tr><td><div class="spinner"></div></td></tr></table></pre><br>
|
||||
<input type="button" value="_(Done)_" onclick="done()">
|
||||
<input type="submit" name="#apply" id='#apply' value="_(Save)_" >
|
||||
</form>
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
Menu="OtherSettings"
|
||||
Type="xmenu"
|
||||
Title="Wake on Lan Settings"
|
||||
Icon="fa-bell"
|
||||
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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
exec("ls --indicator-style=none /sys/class/net|grep -P '^eth[1-9][0-9]*$'",$ports);
|
||||
$disabled = _var($var,'fsState')!='Stopped' ? 'disabled' : '';
|
||||
$width = [166,300];
|
||||
$file = '/boot/config/wol.cfg';
|
||||
$current = parse_ini_file($file);
|
||||
if (!isset($current['LOGFILE'])) $current['LOGFILE'] = "syslog"
|
||||
?>
|
||||
<script>
|
||||
showStatus('pid','unraidwold');
|
||||
</script>
|
||||
<form markdown="1" name="WOLsettings" method="POST" action="/update.php" target="progressFrame" >
|
||||
<input type="hidden" name="#file" value="<?=$file;?>">
|
||||
<input type="hidden" name="#command" value="/webGui/scripts/WOL_action">
|
||||
<input type="hidden" name="#arg[1]" value="load">
|
||||
|
||||
_(Enable Wake on Lan)_:
|
||||
: <select name="WOLENABLED" >
|
||||
<?=mk_option($current['WOLENABLED'], "no", _('No'))?>
|
||||
<?=mk_option($current['WOLENABLED'], "yes", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:WOL_enable_help:
|
||||
|
||||
_(Enable Docker actions)_:
|
||||
|
||||
: <select name="RUNDOCKER" >
|
||||
<?=mk_option($current['RUNDOCKER'], "y", _('Yes'))?>
|
||||
<?=mk_option($current['RUNDOCKER'], "n", _('No'))?>
|
||||
</select>
|
||||
|
||||
:WOL_run_docker_help:
|
||||
|
||||
_(Enable LXC actions)_:
|
||||
: <select name="RUNLXC" >
|
||||
<?=mk_option($current['RUNLXC'], "y", _('Yes'))?>
|
||||
<?=mk_option($current['RUNLXC'], "n", _('No'))?>
|
||||
</select>
|
||||
|
||||
:WOL_run_LXC_help:
|
||||
|
||||
_(Enable VM actions)_:
|
||||
: <select name="RUNVM" >
|
||||
<?=mk_option($current['RUNVM'], "y", _('Yes'))?>
|
||||
<?=mk_option($current['RUNVM'], "n", _('No'))?>
|
||||
</select>
|
||||
|
||||
:WOL_run_VM_help:
|
||||
|
||||
_(Enable Shutdown actions)_:
|
||||
: <select name="RUNSHUT" >
|
||||
<?=mk_option($current['RUNSHUT'], "n", _('No'))?>
|
||||
<?=mk_option($current['RUNSHUT'], "y", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:WOL_run_shutdown_help:
|
||||
|
||||
_(Interface to listern on)_:
|
||||
: <select id="INTERFACE" name="INTERFACE" >
|
||||
<?=mk_option(_var($eth0,'INTERFACE'),'eth0','eth0','selected')?>
|
||||
<?foreach ($ports as $port):?>
|
||||
<?if (!locked('eth0',$port)) echo mk_option_check($current['INTERFACE'],$port,$port)?>
|
||||
<?endforeach;?>
|
||||
</select>
|
||||
|
||||
:WOL_interface_help:
|
||||
|
||||
_(Interface promiscuous mode)_:
|
||||
: <select id="IFMODE" name="IFMODE" >
|
||||
<?=mk_option($current['IFMODE'], "n", _('No'))?>
|
||||
<?=mk_option($current['IFMODE'], "y", _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:WOL_promiscuous_mode_help:
|
||||
|
||||
_(Log file)_:
|
||||
: <input name="LOGFILE" class="narrow"type="text" value=<?=$current['LOGFILE']?>>
|
||||
|
||||
|
||||
:WOL_log_file_help:
|
||||
|
||||
|
||||
: <input type="submit" value="_(Apply)_" disabled><input type="button" value="_(Done)_" onclick="done()">
|
||||
</form>
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
/usr/local/emhttp/plugins/dynamix/scripts/WOL_action load &
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
/usr/local/emhttp/plugins/dynamix/include/script/WOL_action stop &
|
||||
@@ -68,6 +68,8 @@ if ($_POST['docker']) {
|
||||
}
|
||||
echo "\0";
|
||||
if ($_POST['vms']) {
|
||||
$vmusage = $_POST['vmusage'];
|
||||
$vmusagehtml = [];
|
||||
$user_prefs = '/boot/config/plugins/dynamix.vm.manager/userprefs.cfg';
|
||||
$vms = $lv->get_domains() ?: [];
|
||||
if (file_exists($user_prefs)) {
|
||||
@@ -78,6 +80,7 @@ if ($_POST['vms']) {
|
||||
natcasesort($vms);
|
||||
}
|
||||
echo "<tr title='' class='updated'><td>";
|
||||
$running = 0;
|
||||
foreach ($vms as $vm) {
|
||||
$res = $lv->get_domain_by_name($vm);
|
||||
$uuid = libvirt_domain_get_uuid_string($res);
|
||||
@@ -123,6 +126,7 @@ if ($_POST['vms']) {
|
||||
$shape = 'play';
|
||||
$status = 'started';
|
||||
$color = 'green-text';
|
||||
$running++;
|
||||
break;
|
||||
case 'paused':
|
||||
case 'pmsuspended':
|
||||
@@ -138,8 +142,30 @@ if ($_POST['vms']) {
|
||||
}
|
||||
$image = substr($icon,-4)=='.png' ? "<img src='$icon' class='img'>" : (substr($icon,0,5)=='icon-' ? "<i class='$icon img'></i>" : "<i class='fa fa-$icon img'></i>");
|
||||
echo "<span class='outer solid vms $status'><span id='vm-$uuid' $menu class='hand'>$image</span><span class='inner'>$vm<br><i class='fa fa-$shape $status $color'></i><span class='state'>"._($status)."</span></span></span>";
|
||||
if ($state == "running") {
|
||||
#Build VM Usage array.
|
||||
$menuusage = sprintf("onclick=\"addVMContext('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')\"", addslashes($vm), addslashes($uuid), addslashes($template), $state, addslashes($vmrcurl), strtoupper($vmrcprotocol), addslashes($log),addslashes($fstype), $vmrcconsole,true);
|
||||
$vmusagehtml[] = "<span class='outer solid vmsuse $status'><span id='vmusage-$uuid' $menuusage class='hand'>$image</span><span class='inner'>$vm<br><i class='fa fa-$shape $status $color'></i><span class='state'>"._($status)."</span></span>";
|
||||
$vmusagehtml[] = "<br><br><span id='vmmetrics-gcpu-".$uuid."'>"._("Loading")."....</span>";
|
||||
$vmusagehtml[] = "<br><span id='vmmetrics-hcpu-".$uuid."'>"._("Loading")."....</span>";
|
||||
$vmusagehtml[] = "<br><span id='vmmetrics-mem-".$uuid."'>"._("Loading")."....</span>";
|
||||
$vmusagehtml[] = "<br><span id='vmmetrics-disk-".$uuid."'>"._("Loading")."....</span>";
|
||||
$vmusagehtml[] = "<br><span id='vmmetrics-net-".$uuid."'>"._("Loading")."....</span>";
|
||||
$vmusagehtml[] = "</span>";
|
||||
}
|
||||
}
|
||||
$none = count($vms) ? _('No running virtual machines') : _('No virtual machines defined');
|
||||
echo "<span id='no_vms' style='display:none'>$none<br><br></span>";
|
||||
echo "</td></tr>";
|
||||
|
||||
echo "\0";
|
||||
echo "<tr title='' class='useupdated'><td>";
|
||||
if ($vmusage == "Y") {
|
||||
foreach ($vmusagehtml as $vmhtml) {
|
||||
echo $vmhtml;
|
||||
}
|
||||
if (!count($vmusagehtml)) echo "<span id='no_usagevms'><br> "._('No running virtual machines')."<br></span>";
|
||||
if ($running < 1 && count($vmusagehtml)) echo "<span id='no_usagevms'><br>". _('No running virtual machines')."<br></span>";
|
||||
echo "</td></tr>";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,4 +291,13 @@ function my_mkdir($dirname,$permissions = 0777,$recursive = false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
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"));
|
||||
else {
|
||||
$realexplode = explode("/",str_replace("/mnt/","",$path));
|
||||
$reallocation = $realexplode[0];
|
||||
}
|
||||
return $reallocation;
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -39,13 +39,13 @@ foreach ($files as $file) {
|
||||
$c = 0;
|
||||
foreach ($fields as $field) {
|
||||
if ($c==5) break;
|
||||
$text = $field ? explode('=',$field,2)[1] : "-";
|
||||
$text = $field ? (explode('=',$field,2)[1]??"") : "-";
|
||||
$tag = ($c<4) ? "" : " data='".str_replace(['alert','warning','normal'],['0','1','2'],$text)."'";
|
||||
echo (!$c++) ? "<tr>".str_replace('*',$text,$td_).date($dynamix['notify']['date'].' '.$dynamix['notify']['time'],$text)."$_td" : "<td$tag>"._($text)."</td>";
|
||||
}
|
||||
echo "<td><a href='#' onclick='$(this).hide();$.post(\"/webGui/include/DeleteLogFile.php\",{log:\"$archive\"},function(){archiveList();});return false' title=\""._('Delete notification')."\"><i class='fa fa-trash-o'></i></a></td></tr>";
|
||||
if ($extra) {
|
||||
$text = explode('=',$field,2)[1];
|
||||
$text = explode('=',$field,2)[1]??"";
|
||||
echo "<tr class='tablesorter-childRow row$row'><td colspan='4'>$text</td><td></td></tr><tr class='tablesorter-childRow row$row'><td colspan='5'></td></tr>";
|
||||
$row++;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ case 't1load':
|
||||
} else {
|
||||
$supporturl = $module['supporturl'];
|
||||
$pluginname = $module['plugin'];
|
||||
$supporthtml = "<span id='link$modname'><a href='$supporturl' target='_blank'><i title='"._("Support page $pluginname")."' class='fa fa-phone-square'></i></a></span>";
|
||||
$supporthtml = "<span id='link$modname'><a href='$supporturl' target='_blank'><i title='"._("Support page")." $pluginname' class='fa fa-phone-square'></i></a></span>";
|
||||
}
|
||||
}
|
||||
if (!empty($module["version"])) $version = " (".$module["version"].")"; else $version = "";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
/* Copyright 2005-2024, Lime Technology
|
||||
* Copyright 2012-2024, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -12,353 +12,15 @@
|
||||
?>
|
||||
<?
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
|
||||
// add translations
|
||||
$_SERVER['REQUEST_URI'] = 'settings';
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
|
||||
function host_lookup_ip($host) {
|
||||
$result = @dns_get_record($host, DNS_A);
|
||||
$ip = $result ? _var($result[0],'ip') : '';
|
||||
return($ip);
|
||||
}
|
||||
function rebindDisabled() {
|
||||
global $isLegacyCert;
|
||||
$rebindtesturl = $isLegacyCert ? "rebindtest.unraid.net" : "rebindtest.myunraid.net";
|
||||
// DNS Rebind Protection - this checks the server but clients could still have issues
|
||||
$validResponse = ["192.168.42.42", "fd42"];
|
||||
$response = host_lookup_ip($rebindtesturl);
|
||||
return in_array(explode('::',$response)[0], $validResponse);
|
||||
}
|
||||
function format_port($port) {
|
||||
return ($port != 80 && $port != 443) ? ':'.$port : '';
|
||||
}
|
||||
function anonymize_host($host) {
|
||||
global $anon;
|
||||
if ($anon) {
|
||||
$host = preg_replace('/.*\.myunraid\.net/', '*.hash.myunraid.net', $host);
|
||||
$host = preg_replace('/.*\.unraid\.net/', 'hash.unraid.net', $host);
|
||||
}
|
||||
return $host;
|
||||
}
|
||||
function anonymize_ip($ip) {
|
||||
global $anon;
|
||||
if ($anon && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) {
|
||||
$ip = "[redacted]";
|
||||
}
|
||||
return $ip;
|
||||
}
|
||||
function generate_internal_host($host, $ip) {
|
||||
if (strpos($host,'.myunraid.net') !== false) {
|
||||
$host = str_replace('*', str_replace('.', '-', $ip), $host);
|
||||
}
|
||||
return $host;
|
||||
}
|
||||
function generate_external_host($host, $ip) {
|
||||
if (strpos($host,'.myunraid.net') !== false) {
|
||||
$host = str_replace('*', str_replace('.', '-', $ip), $host);
|
||||
} elseif (strpos($host,'.unraid.net') !== false) {
|
||||
$host = "www.".$host;
|
||||
}
|
||||
return $host;
|
||||
}
|
||||
function verbose_output($httpcode, $result) {
|
||||
global $cli, $verbose, $anon, $plgversion, $post, $var, $isRegistered, $myservers, $reloadNginx, $nginx, $isLegacyCert;
|
||||
global $remoteaccess;
|
||||
global $icon_warn, $icon_ok;
|
||||
if (!$cli || !$verbose) return;
|
||||
|
||||
if ($anon) echo "(Output is anonymized, use '-vv' to see full details)".PHP_EOL;
|
||||
echo "Unraid OS "._var($var,'version','???').((strpos($plgversion, "base-") === false) ? " with My Servers plugin version {$plgversion}" : '').PHP_EOL;
|
||||
echo ($isRegistered) ? "{$icon_ok}Signed in to Unraid.net as {$myservers['remote']['username']}".PHP_EOL : "{$icon_warn}Not signed in to Unraid.net".PHP_EOL ;
|
||||
echo "Use SSL is "._var($nginx,'NGINX_USESSL','No').PHP_EOL;
|
||||
echo (rebindDisabled()) ? "{$icon_ok}Rebind protection is disabled" : "{$icon_warn}Rebind protection is enabled";
|
||||
echo " for ".($isLegacyCert ? "unraid.net" : "myunraid.net").PHP_EOL;
|
||||
if ($post) {
|
||||
$wanip = trim(@file_get_contents("https://wanip4.unraid.net/"));
|
||||
// check the data
|
||||
$certhostname = _var($nginx,'NGINX_CERTNAME');
|
||||
if ($certhostname) {
|
||||
// $certhostname is $nginx['NGINX_CERTNAME'] (certificate_bundle.pem)
|
||||
$certhostip = host_lookup_ip(generate_internal_host($certhostname, _var($post,'internalip')));
|
||||
$certhosterr = ($certhostip != _var($post,'internalip'));
|
||||
}
|
||||
if (_var($post,'internalhostname') != $certhostname) {
|
||||
// $post['internalhostname'] is $nginx['NGINX_LANMDNS'] (no cert, or Server_unraid_bundle.pem) || $nginx['NGINX_CERTNAME'] (certificate_bundle.pem)
|
||||
$internalhostip = host_lookup_ip(generate_internal_host(_var($post,'internalhostname'), _var($post,'internalip')));
|
||||
$internalhosterr = ($internalhostip != _var($post,'internalip'));
|
||||
}
|
||||
if (!empty($post['externalhostname'])) {
|
||||
// $post['externalhostname'] is $nginx['NGINX_CERTNAME'] (certificate_bundle.pem)
|
||||
$externalhostip = host_lookup_ip(generate_external_host($post['externalhostname'], $wanip));
|
||||
$externalhosterr = ($externalhostip != $wanip);
|
||||
}
|
||||
// anonymize data. no caclulations can be done with this data beyond this point.
|
||||
if ($anon) {
|
||||
if (!empty($certhostip)) $certhostip = anonymize_ip($certhostip);
|
||||
if (!empty($certhostname)) $certhostname = anonymize_host($certhostname);
|
||||
if (!empty($internalhostip)) $internalhostip = anonymize_ip($internalhostip);
|
||||
if (!empty($externalhostip)) $externalhostip = anonymize_ip($externalhostip);
|
||||
if (!empty($wanip)) $wanip = anonymize_ip($wanip);
|
||||
if (!empty($post['internalip'])) $post['internalip'] = anonymize_ip($post['internalip']);
|
||||
if (!empty($post['internalhostname'])) $post['internalhostname'] = anonymize_host($post['internalhostname']);
|
||||
if (!empty($post['externalhostname'])) $post['externalhostname'] = anonymize_host($post['externalhostname']);
|
||||
if (!empty($post['externalport'])) $post['externalport'] = "[redacted]";
|
||||
}
|
||||
// always anonymize the keyfile
|
||||
if (!empty($post['keyfile'])) $post['keyfile'] = "[redacted]";
|
||||
// output notes
|
||||
if (!empty($post['internalprotocol']) && !empty($post['internalhostname']) && !empty($post['internalport'])) {
|
||||
$localurl = $post['internalprotocol']."://".generate_internal_host($post['internalhostname'], _var($post,'internalip')).format_port($post['internalport']);
|
||||
echo 'Local Access url: '.$localurl.PHP_EOL;
|
||||
if ($internalhostip) {
|
||||
// $internalhostip will not be defined for .local domains, ok to skip
|
||||
echo ($internalhosterr) ? $icon_warn : $icon_ok;
|
||||
echo generate_internal_host($post['internalhostname'], _var($post,'internalip'))." resolves to {$internalhostip}";
|
||||
echo ($internalhosterr) ? ", it should resolve to "._var($post,'internalip') : "";
|
||||
echo PHP_EOL;
|
||||
}
|
||||
if ($certhostname) {
|
||||
echo ($certhosterr) ? $icon_warn : $icon_ok;
|
||||
echo generate_internal_host($certhostname, _var($post,'internalip')).' ';
|
||||
echo ($certhostip) ? "resolves to {$certhostip}" : "does not resolve to an IP address";
|
||||
echo ($certhosterr) ? ", it should resolve to "._var($post,'internalip') : "";
|
||||
echo PHP_EOL;
|
||||
}
|
||||
if ($remoteaccess == 'yes' && !empty($post['externalprotocol']) && !empty($post['externalhostname']) && !empty($post['externalport'])) {
|
||||
$remoteurl = $post['externalprotocol']."://".generate_external_host($post['externalhostname'], $wanip).format_port($post['externalport']);
|
||||
echo 'Remote Access url: '.$remoteurl.PHP_EOL;
|
||||
echo ($externalhosterr) ? $icon_warn : $icon_ok;
|
||||
echo generate_external_host($post['externalhostname'], $wanip).' ';
|
||||
echo ($externalhosterr) ? "does not resolve to an IP address" : "resolves to ".($externalhostip??'');
|
||||
echo PHP_EOL;
|
||||
}
|
||||
if ($reloadNginx) {
|
||||
echo "IP address changes were detected, nginx was reloaded".PHP_EOL;
|
||||
}
|
||||
}
|
||||
// output post data
|
||||
echo PHP_EOL.'Request:'.PHP_EOL;
|
||||
echo @json_encode($post, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . PHP_EOL;
|
||||
}
|
||||
if ($result) {
|
||||
echo "Response (HTTP $httpcode):".PHP_EOL;
|
||||
$mutatedResult = is_array($result) ? json_encode($result) : $result;
|
||||
echo @json_encode(@json_decode($mutatedResult, true), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . PHP_EOL;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @name response_complete
|
||||
* @param {HTTP Response Status Code} $httpcode https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
|
||||
* @param {String|Array} $result - strings are assumed to be encoded JSON. Arrays will be encoded to JSON.
|
||||
* @param {String} $cli_success_msg
|
||||
*/
|
||||
function response_complete($httpcode, $result, $cli_success_msg='') {
|
||||
global $cli, $verbose;
|
||||
$mutatedResult = is_array($result) ? json_encode($result) : $result;
|
||||
if ($cli) {
|
||||
if ($verbose) verbose_output($httpcode, $result);
|
||||
$json = @json_decode($mutatedResult,true);
|
||||
if (!empty($json['error'])) {
|
||||
echo 'Error: '.$json['error'].PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
exit($cli_success_msg.PHP_EOL);
|
||||
}
|
||||
header('Content-Type: application/json');
|
||||
http_response_code($httpcode);
|
||||
exit((string)$mutatedResult);
|
||||
}
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
|
||||
// This is a stub, does nothing but return success
|
||||
my_logger("This is a stub and should not be called", "UpdateDNS");
|
||||
$cli = php_sapi_name()=='cli';
|
||||
$verbose = $anon = false;
|
||||
if ($cli && ($argc > 1) && $argv[1] == "-v") {
|
||||
$verbose = true;
|
||||
$anon = true;
|
||||
}
|
||||
if ($cli && ($argc > 1) && $argv[1] == "-vv") {
|
||||
$verbose = true;
|
||||
}
|
||||
$var = (array)@parse_ini_file('/var/local/emhttp/var.ini');
|
||||
$nginx = (array)@parse_ini_file('/var/local/emhttp/nginx.ini');
|
||||
$is69 = version_compare(_var($var,'version'),"6.9.9","<");
|
||||
$reloadNginx = false;
|
||||
$dnserr = false;
|
||||
$icon_warn = "⚠️ ";
|
||||
$icon_ok = "✅ ";
|
||||
|
||||
$myservers_flash_cfg_path='/boot/config/plugins/dynamix.my.servers/myservers.cfg';
|
||||
$myservers = (array)@parse_ini_file($myservers_flash_cfg_path,true);
|
||||
// ensure some vars are defined here so we don't have to test them later
|
||||
if (empty($myservers['remote']['apikey'])) {
|
||||
$myservers['remote']['apikey'] = "";
|
||||
}
|
||||
if (empty($myservers['remote']['wanaccess'])) {
|
||||
$myservers['remote']['wanaccess'] = "no";
|
||||
}
|
||||
if (empty($myservers['remote']['wanport'])) {
|
||||
$myservers['remote']['wanport'] = 443;
|
||||
}
|
||||
// remoteaccess, externalport
|
||||
if ($cli) {
|
||||
$remoteaccess = empty($nginx['NGINX_WANFQDN']) ? 'no' : 'yes';
|
||||
$externalport = $myservers['remote']['wanport'];
|
||||
} else {
|
||||
$remoteaccess = _var($_POST,'remoteaccess','no');
|
||||
$externalport = intval(_var($_POST,'externalport',443));
|
||||
|
||||
if ($remoteaccess != 'yes') {
|
||||
$remoteaccess = 'no';
|
||||
}
|
||||
|
||||
if ($externalport < 1 || $externalport > 65535) {
|
||||
$externalport = 443;
|
||||
}
|
||||
|
||||
if ($myservers['remote']['wanaccess'] != $remoteaccess) {
|
||||
// update the wanaccess ini value
|
||||
$orig = file_exists($myservers_flash_cfg_path) ? parse_ini_file($myservers_flash_cfg_path,true) : [];
|
||||
if (!$orig) {
|
||||
$orig = ['remote' => $myservers['remote']];
|
||||
}
|
||||
$orig['remote']['wanaccess'] = $remoteaccess;
|
||||
$text = '';
|
||||
foreach ($orig as $section => $block) {
|
||||
$pairs = "";
|
||||
foreach ($block as $key => $value) if (strlen($value)) $pairs .= "$key=\"$value\"\n";
|
||||
if ($pairs) $text .= "[$section]\n".$pairs;
|
||||
}
|
||||
if ($text) file_put_contents($myservers_flash_cfg_path, $text);
|
||||
// need nginx reload
|
||||
$reloadNginx = true;
|
||||
}
|
||||
exit("success".PHP_EOL);
|
||||
}
|
||||
$isRegistered = !empty($myservers['remote']['username']);
|
||||
|
||||
// protocols, hostnames, ports
|
||||
$internalprotocol = 'http';
|
||||
$internalport = _var($nginx,'NGINX_PORT');
|
||||
$internalhostname = _var($nginx,'NGINX_LANMDNS');
|
||||
$externalprotocol = 'https';
|
||||
// keyserver will expand *.hash.myunraid.net or add www to hash.unraid.net as needed
|
||||
$externalhostname = _var($nginx,'NGINX_CERTNAME');
|
||||
$isLegacyCert = preg_match('/.*\.unraid\.net$/', _var($nginx,'NGINX_CERTNAME'));
|
||||
$isWildcardCert = preg_match('/.*\.myunraid\.net$/', _var($nginx,'NGINX_CERTNAME'));
|
||||
$internalip = _var($nginx,'NGINX_LANIP');
|
||||
|
||||
if (_var($nginx,'NGINX_USESSL')=='yes') {
|
||||
// When NGINX_USESSL is 'yes' in 6.9, it could be using either Server_unraid_bundle.pem or certificate_bundle.pem
|
||||
// When NGINX_USESSL is 'yes' in 6.10, it is is using Server_unraid_bundle.pem
|
||||
$internalprotocol = 'https';
|
||||
$internalport = _var($nginx,'NGINX_PORTSSL');
|
||||
if ($is69 && _var($nginx,'NGINX_CERTNAME')) {
|
||||
// this is from certificate_bundle.pem
|
||||
$internalhostname = _var($nginx,'NGINX_CERTNAME');
|
||||
}
|
||||
}
|
||||
if (_var($nginx,'NGINX_USESSL')=='auto') {
|
||||
// NGINX_USESSL cannot be 'auto' in 6.9, it is either 'yes' or 'no'
|
||||
// When NGINX_USESSL is 'auto' in 6.10, it is using certificate_bundle.pem
|
||||
$internalprotocol = 'https';
|
||||
$internalport = _var($nginx,'NGINX_PORTSSL');
|
||||
// keyserver will expand *.hash.myunraid.net as needed
|
||||
$internalhostname = _var($nginx,'NGINX_CERTNAME');
|
||||
}
|
||||
|
||||
// My Servers version
|
||||
$plgversion = file_exists("/var/log/plugins/dynamix.unraid.net.plg") ? trim(exec('/usr/local/sbin/plugin version /var/log/plugins/dynamix.unraid.net.plg 2>/dev/null'))
|
||||
: (file_exists("/var/log/plugins/dynamix.unraid.net.staging.plg") ? trim(exec('/usr/local/sbin/plugin version /var/log/plugins/dynamix.unraid.net.staging.plg 2>/dev/null'))
|
||||
: 'base-'._var($var,'version'));
|
||||
|
||||
// only proceed when when signed in or when legacy unraid.net SSL certificate exists
|
||||
if (!$isRegistered && !$isLegacyCert) {
|
||||
response_complete(406, ['error' => _('Nothing to do')]);
|
||||
}
|
||||
|
||||
// keyfile
|
||||
$keyfile = empty($var['regFILE']) ? false : @file_get_contents($var['regFILE']);
|
||||
if ($keyfile === false) {
|
||||
response_complete(406, ['error' => _('Registration key required')]);
|
||||
}
|
||||
$keyfile = @base64_encode($keyfile);
|
||||
|
||||
// build post array
|
||||
$post = [
|
||||
'keyfile' => $keyfile,
|
||||
'plgversion' => $plgversion
|
||||
];
|
||||
if ($isLegacyCert) {
|
||||
// sign in not required to maintain local ddns for unraid.net cert
|
||||
// enable local ddns regardless of use_ssl value
|
||||
$post['internalip'] = $internalip;
|
||||
// if host.unraid.net does not resolve to the internalip and DNS Rebind Protection is disabled, disable caching
|
||||
if (host_lookup_ip(generate_internal_host(_var($nginx,'NGINX_CERTNAME'), $post['internalip'])) != $post['internalip'] && rebindDisabled()) $dnserr = true;
|
||||
}
|
||||
if ($isRegistered) {
|
||||
// if signed in, send data needed to maintain My Servers Dashboard
|
||||
$post['internalhostname'] = $internalhostname;
|
||||
$post['internalport'] = $internalport;
|
||||
$post['internalprotocol'] = $internalprotocol;
|
||||
$post['remoteaccess'] = $remoteaccess;
|
||||
$post['servercomment'] = _var($var,'COMMENT');
|
||||
$post['servername'] = _var($var,'NAME');
|
||||
if ($isWildcardCert) {
|
||||
// keyserver needs the internalip to generate the local access url
|
||||
$post['internalip'] = $internalip;
|
||||
}
|
||||
if ($remoteaccess == 'yes') {
|
||||
// include wanip in the cache file so we can track if it changes
|
||||
$post['_wanip'] = trim(@file_get_contents("https://wanip4.unraid.net/"));
|
||||
$post['externalhostname'] = $externalhostname;
|
||||
$post['externalport'] = $externalport;
|
||||
$post['externalprotocol'] = $externalprotocol;
|
||||
// if wanip.hash.myunraid.net or www.hash.unraid.net does not resolve to the wanip, disable caching
|
||||
if (host_lookup_ip(generate_external_host($post['externalhostname'], $post['_wanip'])) != $post['_wanip']) $dnserr = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if remoteaccess is enabled in 6.10.0-rc3+ and WANIP has changed since nginx started, reload nginx
|
||||
if (_var($post,'_wanip') != _var($nginx,'NGINX_WANIP') && version_compare(_var($var,'version'),"6.10.0-rc2",">")) $reloadNginx = true;
|
||||
// if remoteaccess is currently disabled (perhaps because a wanip was not available when nginx was started)
|
||||
// BUT the system is configured to have it enabled AND a wanip is now available
|
||||
// then reload nginx
|
||||
if ($remoteaccess == 'no' && _var($nginx,'NGINX_WANACCESS') == 'yes' && !empty(trim(@file_get_contents("https://wanip4.unraid.net/")))) $reloadNginx = true;
|
||||
if ($reloadNginx) {
|
||||
exec("/etc/rc.d/rc.nginx reload &>/dev/null");
|
||||
}
|
||||
|
||||
// maxage is 36 hours
|
||||
$maxage = 36*60*60;
|
||||
if ($dnserr || $verbose) $maxage = 0;
|
||||
$datafile = "/tmp/UpdateDNS.txt";
|
||||
$datafiletmp = "/tmp/UpdateDNS.txt.new";
|
||||
$dataprev = @file_get_contents($datafile) ?: '';
|
||||
$datanew = implode("\n",$post)."\n";
|
||||
if ($datanew == $dataprev && (time()-filemtime($datafile) < $maxage)) {
|
||||
response_complete(204, null, _('No change to report'));
|
||||
}
|
||||
file_put_contents($datafiletmp,$datanew);
|
||||
rename($datafiletmp, $datafile);
|
||||
|
||||
// do not submit the wanip, it will be captured from the submission if needed for remote access
|
||||
unset($post['_wanip']);
|
||||
|
||||
// report necessary server details to limetech for DNS updates
|
||||
$ch = curl_init('https://keys.lime-technology.com/account/server/register');
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$result = curl_exec($ch);
|
||||
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ( ($result === false) || ($httpcode != "200") ) {
|
||||
// delete cache file to retry submission on next run
|
||||
@unlink($datafile);
|
||||
response_complete($httpcode ?? "500", ['error' => $error]);
|
||||
}
|
||||
|
||||
response_complete($httpcode, $result, _('success'));
|
||||
header('Content-Type: application/json');
|
||||
http_response_code(204);
|
||||
exit(0);
|
||||
?>
|
||||
|
||||
@@ -1,125 +0,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.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
global $lv;
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/webGui/include/SysDriversHelpers.php";
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
// add translations
|
||||
$_SERVER['REQUEST_URI'] = 'tools';
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt.php";
|
||||
|
||||
function macbyte($val) {
|
||||
if ($val < 16)
|
||||
return '0'.dechex($val);
|
||||
|
||||
return dechex($val);
|
||||
}
|
||||
|
||||
$arrEntries = [];
|
||||
$vms = $lv->get_domains() ?:[];
|
||||
sort($vms,SORT_NATURAL);
|
||||
foreach($vms as $vm){
|
||||
$arrEntries['VM'][$vm]['interfaces'] = $lv->get_nic_info($vm);
|
||||
$arrEntries['VM'][$vm]['name'] = $vm;
|
||||
}
|
||||
|
||||
$DockerClient = new DockerClient();
|
||||
$containers = $DockerClient->getDockerJSON("/containers/json?all=1");
|
||||
foreach($containers as $ct)
|
||||
$arrEntries['Docker'][substr($ct["Names"][0],1)] = [
|
||||
'interfaces' => ['0 '=> ['mac' => isset($ct["NetworkSettings"]["Networks"]["bridge"]["MacAddress"]) ? $ct["NetworkSettings"]["Networks"]["bridge"]["MacAddress"] : ""]],
|
||||
'name' => substr($ct["Names"][0],1),
|
||||
];
|
||||
|
||||
$lxc = explode("\n",shell_exec("lxc-ls -1")) ;
|
||||
$lxcpath = trim(shell_exec("lxc-config lxc.lxcpath"));
|
||||
foreach ($lxc as $lxcname) {
|
||||
if ($lxcname == "") continue;
|
||||
$value = explode("=",shell_exec("cat $lxcpath/$lxcname/config | grep 'hwaddr'"));
|
||||
$arrEntries['LXC'][$lxcname]['interfaces'][0]['mac'] = trim($value[1]);
|
||||
$arrEntries['LXC'][$lxcname]['name'] = $lxcname;
|
||||
}
|
||||
|
||||
if (is_file("/boot/config/wol.json")) $user_mac = json_decode(file_get_contents("/boot/config/wol.json"),true); else $user_mac = [];
|
||||
|
||||
foreach($arrEntries as $key => $data) {
|
||||
$type=$key;
|
||||
foreach($data as $data2){
|
||||
$name=$data2['name'];
|
||||
if (isset($user_mac[$type][$name])) {
|
||||
$name=$name;
|
||||
$arrEntries[$type][$name]['enable'] = $user_mac[$type][$name]['enable'];
|
||||
$arrEntries[$type][$name]['user_mac'] = strtolower($user_mac[$type][$name]['user_mac']);
|
||||
} else {
|
||||
$arrEntries[$type][$name]['enable'] = 'enable';
|
||||
$arrEntries[$type][$name]['user_mac'] = 'None Defined';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch ($_POST['table']) {
|
||||
|
||||
case 't1load':
|
||||
$arrMacs = $arrEntries;
|
||||
$html = "<thead><tr><th>"._('Service')."</th><th>"._('Name')."</th><th>"._('Mac Address')."</th><th>"._('Enabled')."</th><th>"._('User Mac Address')."</th></tr></thead>";
|
||||
$html .= "<tbody>";
|
||||
ksort($arrMacs);
|
||||
foreach($arrMacs as $systype => $m) {
|
||||
foreach($m as $macaddr) {
|
||||
if ($systype == "") continue;
|
||||
|
||||
$html .= "<tr id='row$systype'>";
|
||||
$macs = "";
|
||||
foreach($macaddr['interfaces'] as $intdetail)
|
||||
{
|
||||
$macs .= " {$intdetail['mac']}" ;
|
||||
}
|
||||
$html .= "<td>$systype</td>";
|
||||
$selecttypename="enable;".$systype.";".$macaddr['name'];
|
||||
$mactypename=htmlspecialchars("user_mac;".$systype.";".$macaddr['name']);
|
||||
$mactypeid=htmlspecialchars("user_mac".$systype."".$macaddr['name']);
|
||||
$user_mac_str = '<input type="text" name="'.$mactypename.'" id="'.$mactypeid.'" class="narrow" value="'.htmlspecialchars($macaddr['user_mac']).'" title="'._("random mac, you can supply your own").'" /><a><i onclick="maccreate(\''.$mactypeid.'\')" class="fa fa-refresh mac_generate" title="re-generate random mac address"></i></a>';
|
||||
$html .= "<td>{$macaddr['name']}</td><td id=\"status$systype\">$macs</td><td>";
|
||||
$html .="<select name='$selecttypename' class='audio narrow'>";
|
||||
$html .= mk_option($macaddr["enable"] , "disable", _("Disabled"));
|
||||
$html .= mk_option($macaddr["enable"] , "enable", _("Enabled"));
|
||||
$html .= mk_option($macaddr["enable"] , "shutdown", _("Enabled and Shutdown"));
|
||||
$html .= "</select></td><td>".$user_mac_str."</td></tr>";
|
||||
$text = "";
|
||||
}
|
||||
}
|
||||
if (count($arrMacs) < 1) {
|
||||
$html .= "<tr id='row'>";
|
||||
$html .= "<td></td><td></td><td>"._("No Entries")."</td><td></td><td></td></tr>";
|
||||
}
|
||||
$html .= "</tbody>";
|
||||
|
||||
$rtn = array();
|
||||
$rtn['html'] = $html;
|
||||
echo json_encode($rtn);
|
||||
break;
|
||||
|
||||
case "macaddress":
|
||||
$seed = 1;
|
||||
$prefix = '62:00:00';
|
||||
$prefix .=':'.macbyte(($seed * rand()) % 256).':'.macbyte(($seed * rand()) % 256).':'.macbyte(($seed * rand()) % 256);
|
||||
echo json_encode(['mac' => $prefix]);
|
||||
break;
|
||||
|
||||
}
|
||||
?>
|
||||
@@ -1,180 +0,0 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/webGui/include/Custom.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt.php";
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
|
||||
function getContainerStats($container, $option) {
|
||||
exec("lxc-info " . $container, $content);
|
||||
foreach($content as $index => $string) {
|
||||
if (strpos($string, $option) !== FALSE)
|
||||
return trim(explode(':', $string)[1]);
|
||||
}
|
||||
}
|
||||
|
||||
$mac = strtolower($argv[1]);
|
||||
|
||||
$libvirtd_running = is_file('/var/run/libvirt/libvirtd.pid') ;
|
||||
$dockerd_running = is_file('/var/run/dockerd.pid');
|
||||
$lxc_ls_exist = is_file('/usr/bin/lxc-ls');
|
||||
#$RUNDOCKER = $RUNLXC = $RUNVM = true;
|
||||
extract(parse_ini_file("/boot/config/wol.cfg")) ;
|
||||
if (!isset($RUNLXC)) $RUNLXC = "y";
|
||||
if (!isset($RUNVM)) $RUNVM = "y";
|
||||
if (!isset($RUNDocker)) $RUNDocker = "y";
|
||||
if (!isset($RUNSHUT)) $RUNSHUT = "n";
|
||||
|
||||
$arrEntries = [] ;
|
||||
if ($libvirtd_running && $RUNVM == "y") {
|
||||
$vms = $lv->get_domains();
|
||||
sort($vms,SORT_NATURAL);
|
||||
foreach($vms as $vm){
|
||||
$arrEntries['VM'][$vm]['interfaces'] = $lv->get_nic_info($vm);
|
||||
$arrEntries['VM'][$vm]['name'] = $vm;
|
||||
}
|
||||
}
|
||||
if ($dockerd_running && $RUNDOCKER == "y") {
|
||||
$DockerClient = new DockerClient();
|
||||
$containers = $DockerClient->getDockerJSON("/containers/json?all=1");
|
||||
foreach($containers as $container)
|
||||
$arrEntries['Docker'][ substr($container["Names"][0],1) ] = [
|
||||
'interfaces' => ['0' => ['mac' => isset($container["NetworkSettings"]["Networks"]["bridge"]["MacAddress"]) ? $container["NetworkSettings"]["Networks"]["bridge"]["MacAddress"]:""]],
|
||||
'name' => substr($container["Names"][0],1),
|
||||
'state' => $container["State"],
|
||||
];
|
||||
}
|
||||
|
||||
if ($lxc_ls_exist && $RUNLXC == "y") {
|
||||
$lxc = explode("\n",shell_exec("lxc-ls -1")) ;
|
||||
$lxcpath = trim(shell_exec("lxc-config lxc.lxcpath"));
|
||||
foreach ($lxc as $lxcname) {
|
||||
if ($lxcname == "") continue;
|
||||
$values = explode("=",shell_exec("cat $lxcpath/$lxcname/config | grep 'hwaddr'"));
|
||||
$arrEntries['LXC'][$lxcname]['interfaces'][0]['mac'] = trim($values[1]);
|
||||
$arrEntries['LXC'][$lxcname]['name'] = $lxcname;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_file("/boot/config/wol.json")) $user_mac = json_decode(file_get_contents("/boot/config/wol.json"),true); else $user_mac = [];
|
||||
|
||||
foreach($arrEntries as $typekey => $typedata)
|
||||
{
|
||||
foreach($typedata as $typeEntry){
|
||||
$name=$typeEntry['name'];
|
||||
if (isset($user_mac[$typekey][$name])) {
|
||||
|
||||
$name=$name;
|
||||
|
||||
$arrEntries[$typekey][$name]['enable'] = $user_mac[$typekey][$name]['enable'];
|
||||
$arrEntries[$typekey][$name]['user_mac'] = strtolower($user_mac[$typekey][$name]['user_mac']);
|
||||
|
||||
} else {
|
||||
$arrEntries[$typekey][$name]['enable'] = "enable";
|
||||
$arrEntries[$typekey][$name]['user_mac'] = 'None Defined';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$mac_list=[];
|
||||
foreach($arrEntries as $type => $detail)
|
||||
{
|
||||
foreach($detail as $name => $entryDetail)
|
||||
{
|
||||
foreach($entryDetail['interfaces'] as $interfaces)
|
||||
{
|
||||
$interfaces['mac'] = strtolower($interfaces['mac']);
|
||||
if($interfaces['mac'] == "" && $entryDetail['user_mac'] == "None Defined") continue;
|
||||
if (isset($entryDetail['state'])) $state = $entryDetail['state']; else $state = "";
|
||||
if (isset($entryDetail['enable']) && !$entryDetail['enable'] ) $enable = false; else $enable = true;
|
||||
if ($entryDetail['user_mac'] != "None Defined") {
|
||||
$mac_list[$entryDetail['user_mac']] = [
|
||||
'type' => $type,
|
||||
'name' => $name,
|
||||
'state' => $state,
|
||||
'enable' => $entryDetail['enable'],
|
||||
];
|
||||
}
|
||||
if ($interfaces['mac'] != "") {
|
||||
$mac_list[$interfaces['mac']] = [
|
||||
'type' => $type,
|
||||
'name' => $name,
|
||||
'state' => $state,
|
||||
'enable' => $entryDetail['enable'],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$found = array_key_exists($mac,$mac_list);
|
||||
|
||||
|
||||
if ($found && $mac_list[$mac]['enable'] != "disable") {
|
||||
echo _("Found"). " " . $mac . " " .$mac_list[$mac]['type'] . " " . $mac_list[$mac]['name'];
|
||||
switch ($mac_list[$mac]['type']) {
|
||||
|
||||
case "VM":
|
||||
if ($libvirtd_running && $RUNVM == "y") {
|
||||
$res = $lv->get_domain_by_name($mac_list[$mac]['name']);
|
||||
$dom = $lv->domain_get_info($res);
|
||||
$state = $lv->domain_state_translate($dom['state']);
|
||||
switch ($state) {
|
||||
case 'running':
|
||||
if ($RUNSHUT == "y" && $mac_list[$mac]['enable'] == "shutdown") $lv->domain_shutdown("{$mac_list[$mac]['name']}");
|
||||
break;
|
||||
case 'paused':
|
||||
case 'pmsuspended':
|
||||
$lv->domain_resume("{$mac_list[$mac]['name']}");
|
||||
break;
|
||||
default:
|
||||
$lv->domain_start("{$mac_list[$mac]['name']}");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "LXC":
|
||||
if ($lxc_ls_exist && $RUNLXC == "y") {
|
||||
$state = getContainerStats($mac_list[$mac]['name'], "State");
|
||||
switch ($state) {
|
||||
case 'RUNNING':
|
||||
if ($RUNSHUT == "y" && $mac_list[$mac]['enable'] == "shutdown") shell_exec("lxc-stop {$mac_list[$mac]['name']}");
|
||||
break;
|
||||
case 'FROZEN':
|
||||
shell_exec("lxc-unfreeze {$mac_list[$mac]['name']}");
|
||||
break;
|
||||
default:
|
||||
shell_exec("lxc-start {$mac_list[$mac]['name']}");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "Docker":
|
||||
if ($dockerd_running && $RUNDOCKER == "y") {
|
||||
|
||||
switch ($mac_list[$mac]['state']) {
|
||||
case "running":
|
||||
if ($RUNSHUT == "y" && $mac_list[$mac]['enable'] == "shutdown") shell_exec("docker stop {$mac_list[$mac]['name']}");
|
||||
break;
|
||||
case "exited":
|
||||
case "created":
|
||||
shell_exec("docker start {$mac_list[$mac]['name']}");
|
||||
break;
|
||||
case "paused":
|
||||
shell_exec("docker unpause {$mac_list[$mac]['name']}");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if ($mac_list[$mac]['enable'] == "disable") echo $mac . " " . _(" has not been actioned as set to disabled");
|
||||
else echo _("Not Found"). " " . $mac . " " . _("ignoring or Maybe actions disabled for type(Docker/VM/LXC)");
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -149,4 +149,56 @@ function my_date($fmt, $time) {
|
||||
function my_logger($message, $logger='webgui') {
|
||||
exec('logger -t '.escapeshellarg($logger).' -- '.escapeshellarg($message));
|
||||
}
|
||||
// Original PHP code by Chirp Internet: www.chirpinternet.eu
|
||||
// Please acknowledge use of this code by including this header.
|
||||
// https://www.the-art-of-web.com/php/http-get-contents/
|
||||
// Modified for Unraid
|
||||
/**
|
||||
* Fetches URL and returns content
|
||||
* @param string $url The URL to fetch
|
||||
* @param array $opts Array of options to pass to curl_setopt()
|
||||
* @param array $getinfo Empty array passed by reference, will contain results of curl_getinfo and curl_error
|
||||
* @return string|false $out The fetched content
|
||||
*/
|
||||
function http_get_contents(string $url, array $opts = [], array &$getinfo = NULL) {
|
||||
$ch = curl_init();
|
||||
if(isset($getinfo)) {
|
||||
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 45);
|
||||
curl_setopt($ch, CURLOPT_ENCODING, "");
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_REFERER, "");
|
||||
curl_setopt($ch, CURLOPT_FAILONERROR, true);
|
||||
if(is_array($opts) && $opts) {
|
||||
foreach($opts as $key => $val) {
|
||||
curl_setopt($ch, $key, $val);
|
||||
}
|
||||
}
|
||||
$out = curl_exec($ch);
|
||||
if(isset($getinfo)) {
|
||||
$getinfo = curl_getinfo($ch);
|
||||
}
|
||||
if (curl_errno($ch)) {
|
||||
$msg = curl_error($ch) . " {$url}";
|
||||
if(isset($getinfo)) {
|
||||
$getinfo['error'] = $msg;
|
||||
}
|
||||
my_logger($msg, "http_get_contents");
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
/**
|
||||
* Detect network connectivity via Network Connectivity Status Indicator
|
||||
* @return bool
|
||||
*/
|
||||
function check_network_connectivity(): bool {
|
||||
$url = 'http://www.msftncsi.com/ncsi.txt';
|
||||
$out = http_get_contents($url);
|
||||
return ($out=="Microsoft NCSI");
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -39,4 +39,8 @@ if ($_SERVER['SCRIPT_NAME'] != '/login.php' && $_SERVER['SCRIPT_NAME'] != '/auth
|
||||
if ($var['csrf_token'] != $_POST['csrf_token']) csrf_terminate("wrong");
|
||||
unset($_POST['csrf_token']);
|
||||
}
|
||||
$proxy_cfg = (array)@parse_ini_file('/var/local/emhttp/proxy.ini',true);
|
||||
putenv('http_proxy='.((array_key_exists('http_proxy', $proxy_cfg)) ? $proxy_cfg['http_proxy'] : ''));
|
||||
putenv('https_proxy='.((array_key_exists('https_proxy', $proxy_cfg)) ? $proxy_cfg['https_proxy'] : ''));
|
||||
putenv('no_proxy='.((array_key_exists('http_proxy', $proxy_cfg)) ? $proxy_cfg['no_proxy'] : ''));
|
||||
?>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<?
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
|
||||
// add translations
|
||||
$_SERVER['REQUEST_URI'] = 'settings';
|
||||
@@ -425,11 +426,10 @@ case 'public':
|
||||
$ip = _var($_POST,'#ip');
|
||||
$v4 = _var($_POST,'#prot')!='6';
|
||||
$v6 = _var($_POST,'#prot')!='';
|
||||
$context = stream_context_create(['https'=>['timeout'=>12]]);
|
||||
$int_ipv4 = $v4 ? (preg_match("/^$validIP4$/",$ip) ? $ip : (@dns_get_record($ip,DNS_A)[0]['ip'] ?: '')) : '';
|
||||
$ext_ipv4 = $v4 ? (@file_get_contents('https://wanip4.unraid.net',false,$context) ?: '') : '';
|
||||
$ext_ipv4 = $v4 ? (http_get_contents('https://wanip4.unraid.net') ?: '') : '';
|
||||
$int_ipv6 = $v6 ? (preg_match("/^$validIP6$/",$ip) ? $ip : (@dns_get_record($ip,DNS_AAAA)[0]['ipv6'] ?: '')) : '';
|
||||
$ext_ipv6 = $v6 ? (@file_get_contents('https://wanip6.unraid.net',false,$context) ?: '') : '';
|
||||
$ext_ipv6 = $v6 ? (http_get_contents('https://wanip6.unraid.net') ?: '') : '';
|
||||
echo "$int_ipv4;$ext_ipv4;$int_ipv6;$ext_ipv6";
|
||||
break;
|
||||
case 'addtunnel':
|
||||
|
||||
@@ -78,7 +78,7 @@ function device_info(&$disk,$online) {
|
||||
$help .= "<br>"._("Click to spin $action device");
|
||||
}
|
||||
$status = "<a class='info'><i ".($ctrl?"id='dev-$named' ":"")."class='fa fa-$orb orb $color-orb'$ctrl></i><span>$help</span></a>";
|
||||
$link = (($parity || $data || $pool) && !str_contains($disk_status,'_NP')) || $name=='flash' || in_array($name,$pools) || $type=='New'
|
||||
$link = (($parity || $data || $pool) && $disk_status!='DISK_NP') || $name=='flash' || in_array($name,$pools) || $type=='New'
|
||||
? "<a href=\"".htmlspecialchars("/Main/Settings/$source?name=$name")."\">$fancy</a>"
|
||||
: $fancy;
|
||||
return $view.$status.$link;
|
||||
|
||||
@@ -20,10 +20,12 @@ require_once "$docroot/webGui/include/publish.php";
|
||||
|
||||
while (true) {
|
||||
$echo = shell_exec("$notify get");
|
||||
$md5_new = md5($echo,true);
|
||||
if ($md5_new !== $md5_old) {
|
||||
publish('notify', $echo);
|
||||
$md5_old = $md5_new;
|
||||
if ( $echo ) {
|
||||
$md5_new = md5($echo,true);
|
||||
if ($md5_new !== $md5_old) {
|
||||
publish('notify', $echo);
|
||||
$md5_old = $md5_new;
|
||||
}
|
||||
}
|
||||
sleep(3);
|
||||
}
|
||||
|
||||
Executable
+91
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/php -q
|
||||
<?PHP
|
||||
/* Copyright 2005-2024, Lime Technology
|
||||
* Copyright 2024-2024, Simon Fairweather.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = '/usr/local/emhttp';
|
||||
$varroot = '/var/local/emhttp';
|
||||
$md5_old = -1;
|
||||
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/webGui/include/publish.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
global $vmusagestats;
|
||||
exec("/etc/rc.d/rc.libvirt status >/dev/null",$dummy,$libvirtd);
|
||||
$libvirtd = $libvirtd==0;
|
||||
if (!$libvirtd) return;
|
||||
|
||||
extract(parse_plugin_cfg('dynamix',true));
|
||||
get_vm_usage_stats();
|
||||
sleep(1);
|
||||
|
||||
// add translations
|
||||
$_SERVER['REQUEST_URI'] = 'dashboard';
|
||||
$login_locale = _var($display,'locale');
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
|
||||
// remember current language
|
||||
$locale_init = $locale;
|
||||
function update_translation($locale) {
|
||||
global $docroot,$language;
|
||||
$language = [];
|
||||
if ($locale) {
|
||||
$text = "$docroot/languages/$locale/translations.txt";
|
||||
if (file_exists($text)) {
|
||||
$store = "$docroot/languages/$locale/translations.dot";
|
||||
if (!file_exists($store)) file_put_contents($store,serialize(parse_lang_file($text)));
|
||||
$language = unserialize(file_get_contents($store));
|
||||
}
|
||||
$text = "$docroot/languages/$locale/dashboard.txt";
|
||||
if (file_exists($text)) {
|
||||
$store = "$docroot/languages/$locale/dashboard.dot";
|
||||
if (!file_exists($store)) file_put_contents($store,serialize(parse_lang_file($text)));
|
||||
$language = array_merge($language,unserialize(file_get_contents($store)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$domain_cfgfile = "/boot/config/domain.cfg";
|
||||
$domain_cfg = parse_ini_file($domain_cfgfile);
|
||||
if (isset($domain_cfg['USAGE']) && $domain_cfg['USAGE'] != 'Y' ) return;
|
||||
if (!isset($domain_cfg['USAGETIMER'])) $timer = 3 ; else $timer = $domain_cfg['USAGETIMER'];
|
||||
|
||||
while (true) {
|
||||
extract(parse_plugin_cfg('dynamix',true));
|
||||
if (_var($display,'locale') != $locale_init) {
|
||||
$locale_init = _var($display,'locale');
|
||||
update_translation($locale_init);
|
||||
}
|
||||
|
||||
get_vm_usage_stats();
|
||||
$echo = [];
|
||||
foreach ($vmusagestats as $vm => $vmdata) {
|
||||
|
||||
if ($vmdata['state'] == 1) {
|
||||
$vmencode = str_replace(" "," ",$vm);
|
||||
$vmencode = $lv->domain_get_uuid($vm);
|
||||
$echo[$vmencode ]['gcpu'] = "<span class='advanced'>"._("Guest CPU").": <span class='cpug-".$vm."'>".$vmdata['cpuguest']."%</span><div class='usage-disk mm'><span id='cpug-".$vm."' style='width:".$vmdata['cpuguest']."%;'></span><span></span></div></span>";
|
||||
$echo[$vmencode ]['hcpu'] = "<span class='advanced'>"._("Host CPU").": <span class='cpug-".$vm."'>".$vmdata['cpuhost']."%</span><div class='usage-disk mm'><span id='cpug-".$vm."' style='width:".$vmdata['cpuhost']."%;'></span><span></span></div></span>";
|
||||
$echo[$vmencode ]['mem'] .= "<span>Mem: ".my_scale($vmdata['mem'],$unit)."$unit / ".my_scale($vmdata['maxmem'],$unit)."$unit</span>";
|
||||
$echo[$vmencode ]['disk'] .= "<span>Disk: "._("Rd").": ".my_scale($vmdata['rdrate'],$unit)."$unit/s "._("Wr").": ".my_scale($vmdata['wrrate'],$unit)."$unit/s</span>";
|
||||
$echo[$vmencode ]['net'] .= "<span>Net: "._("RX").": ".my_scale($vmdata['rxrate'],$unit)."$unit/s "._("TX").": ".my_scale($vmdata['txrate'],$unit)."$unit/s</span>";
|
||||
}
|
||||
}
|
||||
|
||||
$echo = json_encode($echo);
|
||||
$md5_new = md5($echo,true);
|
||||
if ($md5_new !== $md5_old) {
|
||||
$md5_old = publish('vm_dashusage',$echo)!==false ? $md5_new : -1;
|
||||
}
|
||||
sleep($timer);
|
||||
}
|
||||
?>
|
||||
@@ -1,93 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# script: WOL_action
|
||||
#
|
||||
# Startup script for unraidwold
|
||||
#
|
||||
# Simon Fairweather - Initial Script October 2023
|
||||
|
||||
DAEMON="unraidwold"
|
||||
BINARY="/usr/local/bin/unraidwold"
|
||||
|
||||
# run & log functions
|
||||
. /etc/rc.d/rc.runlog
|
||||
. /boot/config/wol.cfg
|
||||
|
||||
unraidwold_running(){
|
||||
sleep 0.1
|
||||
ps axc | grep -q ' unraidwold'
|
||||
}
|
||||
|
||||
unraidwold_start(){
|
||||
log "Starting $DAEMON..."
|
||||
local REPLY
|
||||
if unraidwold_running; then
|
||||
REPLY="Already started"
|
||||
else
|
||||
nohup $BINARY $1 $2 $3 $4 $5 $6 > /dev/null &
|
||||
fi
|
||||
log "$DAEMON... $REPLY."
|
||||
}
|
||||
|
||||
unraidwold_stop(){
|
||||
log "Stopping $DAEMON..."
|
||||
local REPLY
|
||||
if ! unraidwold_running; then
|
||||
REPLY="Already stopped"
|
||||
else
|
||||
killall -TERM $DAEMON
|
||||
if ! unraidwold_running; then REPLY="Stopped"; else REPLY="Failed"; fi
|
||||
fi
|
||||
log "$DAEMON... $REPLY."
|
||||
}
|
||||
|
||||
unraidwold_status(){
|
||||
if unraidwold_running; then
|
||||
echo "$DAEMON is currently running."
|
||||
else
|
||||
echo "$DAEMON is not running."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
unraidwold_load()
|
||||
{
|
||||
if unraidwold_running; then
|
||||
unraidwold_stop
|
||||
fi
|
||||
sleep 1
|
||||
if [ "$WOLENABLED" == "yes" ]; then
|
||||
interfacemode=""
|
||||
logoptions=""
|
||||
|
||||
if [ "$IFMODE" == "y" ]; then
|
||||
interfacemode="--promiscuous"
|
||||
fi
|
||||
|
||||
if [ "$LOGFILE" != "syslog" ]; then
|
||||
logoptions="--log $LOGFILE"
|
||||
fi
|
||||
|
||||
unraidwold_start --interface $INTERFACE $interfacemode $logoptions
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
'start')
|
||||
unraidwold_start $2 $3 $4 $5 $6
|
||||
;;
|
||||
'stop')
|
||||
unraidwold_stop
|
||||
;;
|
||||
'status')
|
||||
unraidwold_status
|
||||
;;
|
||||
'load')
|
||||
unraidwold_load
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $BDAEMON start|stop|restart|status"
|
||||
exit 1
|
||||
esac
|
||||
exit 0
|
||||
@@ -25,6 +25,7 @@ $zip = $all ? ($argv[2]??'') : ($argv[1]??'');
|
||||
$cli = empty($zip);
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
|
||||
$folders = ['/boot','/boot/config','/boot/config/plugins','/boot/syslinux','/var/log','/var/log/plugins','/boot/extra','/var/log/packages','/var/lib/pkgtools/packages','/tmp'];
|
||||
@@ -115,16 +116,6 @@ function maskIP($file) {
|
||||
// anonymize full IPv6 addresses
|
||||
run("sed -ri 's/([\"\[ ]([0-9a-f]{1,4}:){4})(([0-9a-f]{1,4}:){3}|:)([0-9a-f]{1,4})([/\" .]|$)/\\1XXXX:XXXX:XXXX:\\5\\6/g' ".escapeshellarg($file)." 2>/dev/null");
|
||||
}
|
||||
|
||||
function cache_only($disk) {
|
||||
return _var($disk,'type')=='Cache';
|
||||
}
|
||||
function cache_filter($disks) {
|
||||
return array_filter($disks,'cache_only');
|
||||
}
|
||||
function pools_filter($disks) {
|
||||
return array_unique(array_map('prefix',array_keys(cache_filter($disks))));
|
||||
}
|
||||
function download_url($url, $path="", $bg=false, $timeout=15) {
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch,[
|
||||
@@ -661,6 +652,13 @@ if (file_exists($dhcplog)) {
|
||||
if (!$all) maskIP($log);
|
||||
}
|
||||
|
||||
// copy phplog
|
||||
$phplog = "/var/log/phplog";
|
||||
if (file_exists($phplog)) {
|
||||
$log = "/$diag/logs/phplog.txt";
|
||||
run("todos <$phplog >".escapeshellarg($log));
|
||||
}
|
||||
|
||||
// copy graphql-api.log
|
||||
$graphql = "/var/log/graphql-api.log";
|
||||
if (file_exists($graphql)) {
|
||||
|
||||
@@ -35,7 +35,7 @@ if [[ -n $local_server ]]; then
|
||||
sed -ri "\$a\\\$InputUDPServerBindRuleset remote\n\\\$UDPServerRun ${server_port:-514}" $ETC
|
||||
[[ $server_protocol == udp ]] && sed -ri 's/^(\$ModLoad imtcp)/#\1/;/^\$InputTCPServerBindRuleset remote$/d;/^\$InputTCPServerRun [0-9]+$/d' $ETC
|
||||
fi
|
||||
sed -ri "/^\\\$template remote,.*$/d;/^#\\\$UDPServerRun [0-9]+.*$/a\\\$template remote,\"${server_folder:-/mnt/user/system}/syslog-%FROMHOST-IP%.log\"" $ETC
|
||||
sed -ri "/^\\\$template remote,.*$/d;/^#\\\$UDPServerRun [0-9]+.*$/a\\\$template remote,\"${server_folder:-/mnt/user/system}/${server_filename:-syslog-%FROMHOST-IP%.log}\"" $ETC
|
||||
else
|
||||
sed -ri '/^\$RuleSet remote$/d;/^\$FileOwner nobody$/d;/^\$FileGroup users$/d;/^\$FileCreateMode 06[46][46]$/d;/^\$IncludeConfig \/etc\/rsyslog\.d\/\*\.conf # remote$/d;/^\*\.\* \?remote$/d;/^\$template remote,".*"$/d;/^\$Input(TCP|UDP)ServerBindRuleset remote$/d;/^\$(InputTCP|UDP)ServerRun [0-9]+$/d;s/^#?\$(ModLoad imtcp|ModLoad imudp)/#\$\1/' $ETC
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/php -q
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
/* Copyright 2005-2024, Lime Technology
|
||||
* Copyright 2012-2024, 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,
|
||||
@@ -21,6 +21,7 @@ $disks = (array)@parse_ini_file("/var/local/emhttp/disks.ini",true);
|
||||
require_once "$docroot/webGui/include/CustomMerge.php";
|
||||
|
||||
$script = "$docroot/webGui/scripts/notify";
|
||||
// this command will set the $notify array
|
||||
extract(parse_plugin_cfg("dynamix",true));
|
||||
$output = _var($notify,'report');
|
||||
$server = strtoupper(_var($var,'NAME','tower'));
|
||||
@@ -178,7 +179,8 @@ $warn = ($error0 || $error3) ? "alert" : (($error1 || $error2) ? "warning" : "no
|
||||
$stat = $warn=="normal" ? "[PASS]" : "[FAIL]";
|
||||
$info = "Array has $size disk".($size==1 ? "" : "s").($parity ? " ({$word}parity".($pools ? " & pools)" : ")") : ($pools ? " ({$word}pools)" : ""));
|
||||
$message = implode('\n', $data);
|
||||
exec("$script -s ".escapeshellarg("Notice [$server] - array health report $stat")." -d ".escapeshellarg("$info")." -m ".escapeshellarg("$message")." -i ".escapeshellarg("$warn $output")." -l '/Main'");
|
||||
$subject = "Notice [$server] - array health report $stat";
|
||||
exec("$script -s ".escapeshellarg($subject)." -d ".escapeshellarg("$info")." -m ".escapeshellarg("$message")." -i ".escapeshellarg("$warn $output")." -l '/Main'");
|
||||
|
||||
exit(0);
|
||||
?>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
table#t1{margin-top:0;font-family:clear-sans}
|
||||
table#t1 thead tr th{font-weight:bold}
|
||||
table#t1 tbody tr td{padding:4px 20px 4px 0;margin:0;text-align:left;white-space:normal}
|
||||
table#t1 tbody tr td:nth-child(1){width:10%}
|
||||
table#t1 tbody tr td:nth-child(2){width:30%}
|
||||
table#t1 tbody tr td:nth-child(3){width:15%}
|
||||
table#t1 tbody tr td:nth-child(4){width:20%}
|
||||
table#t1 tbody tr td:nth-child(5){width:25%;padding-right:0}
|
||||
table.t1.tablesorter .filtered{display:none}
|
||||
.tablesorter-header-inner{font-family:clear-sans;font-weight:bold}
|
||||
#macform .mac_generate{cursor:pointer;margin-left:-5px;color:#08C;font-size:1.3rem;transform:translate(0px, 2px)}
|
||||
@@ -122,7 +122,9 @@ table.unraid thead tr:first-child>td{font-size:1.2rem;text-transform:uppercase;l
|
||||
table.unraid tbody tr:not(.tr_last):hover>td{background-color:rgba(0,0,0,0.05)}
|
||||
table.unraid tr>td{overflow:hidden;text-overflow:ellipsis;padding-left:8px}
|
||||
table.unraid tr>td:hover{overflow:visible}
|
||||
table.legacy{table-layout:auto}
|
||||
table.legacy{table-layout:auto!important}
|
||||
table.legacy thead td{line-height:normal;height:auto;padding:7px 0}
|
||||
table.legacy tbody td{line-height:normal;height:auto;padding:5px 0}
|
||||
table.disk_status{table-layout:fixed}
|
||||
table.disk_status tr>td:last-child{padding-right:8px}
|
||||
table.disk_status tr>td:nth-child(1){width:13%}
|
||||
|
||||
@@ -120,7 +120,9 @@ table.unraid tbody tr:nth-child(even){background-color:#212121}
|
||||
table.unraid tbody tr:not(.tr_last):hover>td{background-color:rgba(255,255,255,0.1)}
|
||||
table.unraid tr>td{overflow:hidden;text-overflow:ellipsis;padding-left:8px}
|
||||
table.unraid tr>td:hover{overflow:visible}
|
||||
table.legacy{table-layout:auto}
|
||||
table.legacy{table-layout:auto!important}
|
||||
table.legacy thead td{line-height:normal;height:auto;padding:7px 0}
|
||||
table.legacy tbody td{line-height:normal;height:auto;padding:5px 0}
|
||||
table.disk_status{table-layout:fixed}
|
||||
table.disk_status tr>td:last-child{padding-right:8px}
|
||||
table.disk_status tr>td:nth-child(1){width:13%}
|
||||
|
||||
@@ -122,7 +122,9 @@ table.unraid thead tr:first-child>td{font-size:1.2rem;text-transform:uppercase;l
|
||||
table.unraid tbody tr:not(.tr_last):hover>td{background-color:rgba(255,255,255,0.05)}
|
||||
table.unraid tr>td{overflow:hidden;text-overflow:ellipsis;padding-left:8px}
|
||||
table.unraid tr>td:hover{overflow:visible}
|
||||
table.legacy{table-layout:auto}
|
||||
table.legacy{table-layout:auto!important}
|
||||
table.legacy thead td{line-height:normal;height:auto;padding:7px 0}
|
||||
table.legacy tbody td{line-height:normal;height:auto;padding:5px 0}
|
||||
table.disk_status{table-layout:fixed}
|
||||
table.disk_status tr>td:last-child{padding-right:8px}
|
||||
table.disk_status tr>td:nth-child(1){width:13%}
|
||||
|
||||
@@ -120,7 +120,9 @@ table.unraid tbody tr:nth-child(even){background-color:#ededed}
|
||||
table.unraid tbody tr:not(.tr_last):hover>td{background-color:rgba(0,0,0,0.1)}
|
||||
table.unraid tr>td{overflow:hidden;text-overflow:ellipsis;padding-left:8px}
|
||||
table.unraid tr>td:hover{overflow:visible}
|
||||
table.legacy{table-layout:auto}
|
||||
table.legacy{table-layout:auto!important}
|
||||
table.legacy thead td{line-height:normal;height:auto;padding:7px 0}
|
||||
table.legacy tbody td{line-height:normal;height:auto;padding:5px 0}
|
||||
table.disk_status{table-layout:fixed}
|
||||
table.disk_status tr>td:last-child{padding-right:8px}
|
||||
table.disk_status tr>td:nth-child(1){width:13%}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.jGrowl{position:fixed;font-size:1.3rem}
|
||||
.jGrowl{position:fixed;font-size:1.3rem;z-index:10001}
|
||||
.jGrowl.top-left{left:10px;top:90px}
|
||||
.jGrowl.top-right{right:10px;top:90px}
|
||||
.jGrowl.bottom-left{left:10px;bottom:24px}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.jGrowl{position:fixed;font-size:1.3rem}
|
||||
.jGrowl{position:fixed;font-size:1.3rem;z-index:10001}
|
||||
.jGrowl.top-left{left:10px;top:130px}
|
||||
.jGrowl.top-right{right:10px;top:130px}
|
||||
.jGrowl.bottom-left{left:10px;bottom:24px}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.jGrowl{position:fixed;font-size:1.3rem}
|
||||
.jGrowl{position:fixed;font-size:1.3rem;z-index:10001}
|
||||
.jGrowl.top-left{left:10px;top:90px}
|
||||
.jGrowl.top-right{right:10px;top:90px}
|
||||
.jGrowl.bottom-left{left:10px;bottom:24px}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.jGrowl{position:fixed;font-size:1.3rem}
|
||||
.jGrowl{position:fixed;font-size:1.3rem;z-index:10001}
|
||||
.jGrowl.top-left{left:10px;top:130px}
|
||||
.jGrowl.top-right{right:10px;top:130px}
|
||||
.jGrowl.bottom-left{left:10px;bottom:24px}
|
||||
|
||||
Reference in New Issue
Block a user