Compare commits

...

61 Commits

Author SHA1 Message Date
Tom Mortensen
2b41f9a8d2 Device Info page:
* Prevent reducing pool slot count unless pool state is NEW_ARRAY
* Permit changing pool file system type only when Stopped
* Add "Delete Pool" button which unassigns all devices of a pool and then removes the pool
* Change button label "Erase" to "Erase Pool"
2024-07-24 02:13:22 -07:00
Tom Mortensen
70c01ec454 Include subpool devices in list of devices to be formatted when appropriate 2024-07-24 02:12:58 -07:00
Tom Mortensen
7840ae6d3c new handling of 'ntp.conf' and 'ntp.conf-' (similar to exports) 2024-07-24 00:41:27 -07:00
Tom Mortensen
5b009dfb39 remove unnecessary symlinks 2024-07-24 00:41:27 -07:00
tom mortensen
5565c02f74 Merge pull request #1796 from desertwitch/desertwitch-patch-1
fix table order breaking when cookie is left malformed
2024-07-24 00:37:19 -07:00
tom mortensen
793289bc7f Merge pull request #1792 from dlandon/master
Fix overlapping text on VPN Manager page; php warning; allow UD disks to show in file picker.
2024-07-24 00:31:21 -07:00
tom mortensen
7d92761860 Merge pull request #1797 from SimonFair/VM-Manager-PHP-Fixes
Fix memory Stats in VM Usage.
2024-07-24 00:29:01 -07:00
tom mortensen
1021adc33b Merge pull request #1799 from dlandon/diagnostocs-ipv6-fix
Diagnostics ipv6 fix
2024-07-24 00:28:11 -07:00
tom mortensen
c9374f7911 Merge pull request #1800 from unraid/use-docs-go-links
Use "go links" when linking to Docs
2024-07-24 00:27:20 -07:00
tom mortensen
73a17a0306 Merge pull request #1802 from bergware/master
Fix broken "show_interface" script
2024-07-24 00:26:44 -07:00
bergware
0729386af9 Fix broken "show_interface" script 2024-07-23 19:41:02 +02:00
bergware
4b8ec6e5a3 Fix broken "show_interface" script 2024-07-23 19:34:40 +02:00
dlandon
ea2fa8a8db Chmod on non-existent file causing php warning. 2024-07-22 09:58:06 -05:00
dlandon
d7e474257c Allow UD disks to be listed in file picker. 2024-07-21 04:55:49 -05:00
SimonFair
e20f37d936 Update emhttp/plugins/dynamix/nchan/vm_dashusage
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2024-07-19 21:04:17 +01:00
ljm42
4c1c566e78 Add trailing slash to go links
Eliminates an unnecessary redirect
2024-07-19 12:02:00 -07:00
ljm42
a6c50b208a Add trailing slash to go links
Eliminates an unnecessary redirect
2024-07-19 12:00:36 -07:00
SimonFair
9a23761dc8 Update vm_dashusage 2024-07-19 19:44:59 +01:00
dlandon
359334b85a Fix another php error. 2024-07-19 12:55:45 -05:00
SimonFair
f5ed6964dd Update vm_usage 2024-07-19 18:55:03 +01:00
SimonFair
882ee7f911 Hide Max if Current and Max are equal 2024-07-19 18:30:45 +01:00
ljm42
234a749b7f Use "go links" when linking to Docs 2024-07-19 10:01:50 -07:00
dlandon
a9891f557e Merge branch 'unraid:master' into master 2024-07-19 10:33:48 -05:00
dlandon
04640a5708 Anonimize IPv6 addresses with square braces. 2024-07-19 10:31:06 -05:00
SimonFair
fac92be4d4 Fix memory Stats in VM Usage.
Three columns inuse/Current/Maximum
2024-07-19 14:21:09 +01:00
Rysz
817ed5c1c1 fix table order breaking when cookie is left malformed 2024-07-18 22:13:13 +02:00
Tom Mortensen
a4abe0fa55 update firefox symlink 2024-07-18 12:14:35 -07:00
dlandon
6920542d6c Merge branch 'unraid:master' into master 2024-07-18 06:14:40 -05:00
dlandon
cfa547972e Fix overlapping text on VPN Manager page. 2024-07-16 13:24:15 -05:00
tom mortensen
84b5baf402 Merge pull request #1791 from ich777/docker-dashboard-patch
Show Docker RAM usage on Dashboard & minor changes
2024-07-16 10:01:16 -07:00
tom mortensen
1b162e2c21 Merge pull request #1790 from dlandon/master
Fix php warning in device_list; VPN Manager not showing tunnel status.
2024-07-16 10:00:44 -07:00
tom mortensen
75f0c2e4f6 Merge pull request #1788 from ich777/initial-overlay2-support
Initial Docker overlay2 support
2024-07-16 09:59:39 -07:00
tom mortensen
67369622fa Merge pull request #1787 from ich777/ipv6-forward
Add IPv6 forward rule
2024-07-16 09:58:49 -07:00
tom mortensen
17fdfb6f50 Merge pull request #1786 from ich777/proxy-fix
fix path
2024-07-16 09:58:10 -07:00
tom mortensen
9e80fb13c7 Merge pull request #1783 from SimonFair/VM-Manager-PHP-Fixes
Move restore favorites after plugin installs + VM Template formatting for PCI others
2024-07-16 09:57:34 -07:00
tom mortensen
1d6c3f4375 Merge pull request #1782 from zackspear/fix/vm-icon-edit
fix: AddVM & UpdateVM icon selection styles
2024-07-16 09:57:10 -07:00
58c31f4ef6 Show Docker RAM usage on Dashboard
- Add Docker RAM usage to Dashbaord page
- Rename 'Services' to 'System'
- Remove 'usage' suffix from Services naming scheme
2024-07-16 13:57:21 +02:00
dlandon
84b767ddcd Fix php[ warning. 2024-07-15 17:32:11 -05:00
dlandon
32d3f88b44 VPN Manager not showing tunnel status. 2024-07-15 17:28:20 -05:00
Zack Spear
6156a2582f fix: UpdateVM.css temlpate img chooser 2024-07-15 13:43:22 -07:00
SimonFair
8a55228b8e Update VMedit.php 2024-07-15 18:59:56 +01:00
SimonFair
fe7ab1fc43 FIX Issue with VM Template formatting for other PCI 2024-07-15 18:41:29 +01:00
30492ed2f2 Initial Docker overlay2 support
- override filesystem type to overlay2 if `DOCKER_BACKINGFS` in docker.cfg is set to `overlay2`
2024-07-15 17:40:10 +02:00
da1ef5c0e0 IPv6 forward
- Add `IPV6_FORWARD` to rc.docker and set it to `ACCEPT` instead of `DROP`
2024-07-15 17:22:48 +02:00
93054c2091 fix path
- fix path for generated proxy file
2024-07-15 15:47:50 +02:00
SimonFair
f2abfaf292 Move restore favorites after plugin installs 2024-07-13 15:33:37 +01:00
Zack Spear
5a42314c60 fix: AddVM & UpdateVM icon selection styles 2024-07-12 14:55:00 -07:00
Tom Mortensen
bbed6047e3 Introduce 'Allocation profile' config setting for specifying pool/subpool data layout
Fix: spindown delay setting missing for parity devices
2024-07-12 11:53:32 -07:00
Tom Mortensen
a7f6ac7389 maybe needed in future 2024-07-10 23:01:09 -07:00
Tom Mortensen
f7748f7619 make executable 2024-07-10 23:00:20 -07:00
Tom Mortensen
d4968e1b19 simplify display of file system type on Main 2024-07-10 22:59:53 -07:00
Tom Mortensen
fb680469ac fix git glitch which resulted in file not updated 2024-07-10 22:58:42 -07:00
tom mortensen
eaabbec7e0 Merge pull request #1780 from unraid/fix-trim
Make trim consistent between "trim now" and cron job
2024-07-10 21:41:39 -07:00
ljm42
693a0260af Make trim consistent between "Run now" and cron job 2024-07-10 17:59:15 -07:00
tom mortensen
130c9c6373 Merge pull request #1779 from ich777/ich777-agents-fix
Fix for notification agents
2024-07-10 14:22:17 -07:00
73c264e9fe Fix
- Fix PushBits and Pushbullet not showing up
2024-07-10 14:47:06 +02:00
667741129a Fix
- Fix PushBits and Pushbullet not showing up
2024-07-10 14:45:49 +02:00
tom mortensen
42fe45595f Merge pull request #1778 from dlandon/master
Parity check does not show completed on array operations page.
2024-07-09 13:44:58 -07:00
dlandon
ed9b8322d4 Fix clobbering CAs $cfg variable. 2024-07-09 14:57:58 -05:00
dlandon
cfb2daa531 Update help text for PID Limit. 2024-07-09 06:37:58 -05:00
dlandon
694d35b412 Parity check does not show completed on array operations page. 2024-07-09 06:21:29 -05:00
39 changed files with 290 additions and 151 deletions

View File

@@ -1 +0,0 @@
/usr/libexec/unraid/firefox-119.0.r20231019122658-x86_64.AppImage

View File

@@ -1 +0,0 @@
/usr/libexec/unraid/unraidwold

View File

@@ -12,11 +12,6 @@
*/
?>
<?
/* Read the docker configuration file. */
$cfgfile = "/boot/config/docker.cfg";
$config_ini = @parse_ini_file($cfgfile, true, INI_SCANNER_RAW);
$cfg = ($config_ini !== false) ? $config_ini : [];
function addRoute($ct) {
// add static route(s) for remote WireGuard access
[$pid,$net] = array_pad(explode(' ',exec("docker inspect --format='{{.State.Pid}} {{.NetworkSettings.Networks}}' $ct")),2,'');
@@ -242,7 +237,7 @@ function xmlSecurity(&$template) {
}
function xmlToCommand($xml, $create_paths=false) {
global $docroot, $var, $cfg, $driver;
global $docroot, $var, $driver;
$xml = xmlToVar($xml);
$cmdName = strlen($xml['Name']) ? '--name='.escapeshellarg($xml['Name']) : '';
$cmdPrivileged = strtolower($xml['Privileged'])=='true' ? '--privileged=true' : '';
@@ -307,12 +302,17 @@ function xmlToCommand($xml, $create_paths=false) {
}
}
/* Read the docker configuration file. */
$cfgfile = "/boot/config/docker.cfg";
$config_ini = @parse_ini_file($cfgfile, true, INI_SCANNER_RAW);
$docker_cfg = ($config_ini !== false) ? $config_ini : [];
// Add pid limit if user has not specified it as an extra parameter
$pidsLimit = preg_match('/--pids-limit (\d+)/', $xml['ExtraParams'], $matches) ? $matches[1] : null;
if ($pidsLimit === null) {
$pid_limit = "--pids-limit ";
if (($cfg['DOCKER_PID_LIMIT']??'') != "") {
$pid_limit .= $cfg['DOCKER_PID_LIMIT'];
if (($docker_cfg['DOCKER_PID_LIMIT']??'') != "") {
$pid_limit .= $docker_cfg['DOCKER_PID_LIMIT'];
} else {
$pid_limit .= "2048";
}

View File

@@ -0,0 +1,28 @@
#!/bin/bash
# Get active containers
ACTIVE_CONTAINERS="$(docker ps -q --no-trunc 2>/dev/null)"
# Exit if no containers are active and return zero
if [ -z "${ACTIVE_CONTAINERS}" ]; then
echo "0"
exit
fi
# Get all relevant memory entries from containers
for container in ${ACTIVE_CONTAINERS} ; do
CONT_MEMORY="$(cat /sys/fs/cgroup/docker/${container}/memory.stat 2>/dev/null | grep -Ew "anon|kernel|kernel_stack|pagetables|sec_pagetables|percpu|sock|vmalloc|shmem" | awk '{print $2}')"
# Add up memory values
for value in ${CONT_MEMORY} ; do
if [[ ${value} =~ ^[0-9]+$ ]]; then
((MEMORY_USAGE += value))
fi
done
unset CONT_MEMORY
done
# Check if value is a integer and return the value otherwiese return zero
if [[ ${MEMORY_USAGE} =~ ^[0-9]+$ ]]; then
echo "${MEMORY_USAGE}"
else
echo "0"
fi

View File

@@ -24,7 +24,7 @@ require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
$hardware = !empty(shell_exec("/etc/rc.d/rc.libvirt test"));
if (!$hardware) {
echo "<p class='notice'>"._('Your hardware does not have Intel VT-x or AMD-V capability').". "._('This is required to create VMs in KVM').". "._('Please disable the VM function').". ";
echo "<a href='https://docs.unraid.net/unraid-os/manual/vm-management#determining-hvmiommu-hardware-support' target='_blank'> "._('Click here to see the Unraid Wiki for more information')."</a></p>";
echo "<a href='https://docs.unraid.net/go/determining-hvmiommu-hardware-support/' target='_blank'> "._('View the Docs for more information')."</a></p>";
}
function scan($area, $text) {

View File

@@ -19,7 +19,7 @@ Cond="exec(\"grep -o '^USAGE=.Y' /boot/config/domain.cfg 2>/dev/null\") && is_fi
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
?>
<table id="vmstats" class="tablesorter four shift">
<thead class='child'><tr><th class="th1">_(Name)_</th><th class="th2">_(Guest CPU)_</th><th>_(Host CPU)_</th><th>_(Memory)_</th><th>_(Disk IO)_</th><th>_(Network IO)_</th></tr></thead>
<thead class='child'><tr><th class="th1">_(Name)_</th><th class="th2">_(Guest CPU)_</th><th>_(Host CPU)_</th><th>_(Memory inuse/Current/Maximum)_</th><th>_(Disk IO)_</th><th>_(Network IO)_</th></tr></thead>
<tbody id ="vmstatsbody" class='child'>
</tbody>
</table>

View File

@@ -113,7 +113,7 @@ if (strpos($strSelectedTemplate,"User-") !== false) {
<table>
<tr>
<td>_(Icon)_:</td>
<td>
<td class="template_img_parent">
<input type="hidden" name="template[icon]" id="template_icon" value="<?=htmlspecialchars($arrLoad['icon'])?>" />
<img id="template_img" src="<?=htmlspecialchars($strIconURL)?>" width="48" height="48" title="_(Change Icon)_..."/>
<div id="template_img_chooser_outer">
@@ -189,13 +189,13 @@ $(function() {
});
$('.advancedview').switchButton({
labels_placement: "left",
labels_placement: "right",
on_label: "_(XML View)_",
off_label: "_(Form View)_",
checked: isVMXMLMode()
});
$('.inlineview').switchButton({
labels_placement: "left",
labels_placement: "right",
off_label: "_(Hide inline xml)_",
on_label: "_(Show Inline XML)_",
checked: isinlineXMLMode()

View File

@@ -2661,8 +2661,8 @@ function get_vm_usage_stats($collectcpustats = true,$collectdiskstats = true,$co
# Memory Metrics
if ($state == 1 && $collectmemstats) {
$currentmem = $data["balloon.current"];
$unusedmem = $data["balloon.unused"];
$meminuse = $currentmem - $unusedmem;
$maximummem = $data["balloon.maximum"];
$meminuse = min($data["balloon.rss"],$data["balloon.current"]);
} else $currentmem = $meminuse = 0;
# Disk
@@ -2697,7 +2697,8 @@ function get_vm_usage_stats($collectcpustats = true,$collectdiskstats = true,$co
"cpuguest" => $cpuGuestPercent,
"timestamp" => $timestamp,
"mem" => $meminuse,
"maxmem" => $currentmem,
"curmem" => $currentmem,
"maxmem" => $maximummem,
"rxrate" => $rxrate,
"rxp" => $rx,
"txrate" => $txrate,

View File

@@ -75,9 +75,11 @@ while (true) {
if ($vmdata['state'] == 1) {
$running++;
$echodata .= "<tr><td>$vm</td>" ;
$echodata .= "<td class='advanced'><span class='cpug-".$vm."'>".$vmdata['cpuguest']."%</span><div class='usage-disk mm'><span id='cpug-".$vm."' style='width:".$vmdata['cpuguest']."%;'></span><span></span></div></td>";
$echodata .= "<td class='advanced'><span class='cpuh-".$vm."'>".$vmdata['cpuhost']."%</span><div class='usage-disk mm'><span id='cpuh-".$vm."' style='width:".$vmdata['cpuhost']."%;'></span><span></span></div></td><td>";
$echodata .= my_scale($vmdata['mem']*1024,$unit)."$unit / ".my_scale($vmdata['maxmem']*1024,$unit)."$unit</td><td>";
$echodata .= "<td class='advanced'><span class='cpug-".$vm."'>".$vmdata['cpuguest']."%</span><div class='usage-disk mm'><span id='cpug-".$vm."' style='width:".$vmdata['cpuguest']."%;'> </span><span></span></div></td>";
$echodata .= "<td class='advanced'><span class='cpuh-".$vm."'>".$vmdata['cpuhost']."%</span><div class='usage-disk mm'><span id='cpuh-".$vm."' style='width:".$vmdata['cpuhost']."%;'> </span><span></span></div></td><td>";
$echodata .= my_scale($vmdata['mem']*1024,$unit)."$unit / ".my_scale($vmdata['curmem']*1024,$unit)."$unit";
if ($vmdata['curmem'] === $vmdata['maxmem']) $echodata .= " </td><td>";
else $echodata .= " / " .my_scale($vmdata['maxmem']*1024,$unit)."$unit </td><td>";
$echodata .= _("Read").": ".my_scale($vmdata['rdrate'],$unit)."$unit/s<br>"._("Write").": ".my_scale($vmdata['wrrate'],$unit)."$unit/s</td><td>";
$echodata .= _("RX").": ".my_scale($vmdata['rxrate'],$unit)."$unit/s<br>"._("TX").": ".my_scale($vmdata['txrate'],$unit)."$unit/s</td></tr>";
}

View File

@@ -23,14 +23,15 @@ span.advancedview_panel{display:none;line-height:16px;margin-top:1px}
.basic{display:none}
.advanced{/*Empty placeholder*/}
.switch-button-label.off{color:inherit}
.template_img_parent{position:relative}
#template_img{cursor:pointer}
#template_img:hover{opacity:0.5}
#template_img:hover i{opacity:1.0}
.template_img_chooser_inner{display:inline-block;width:80px;margin-bottom:15px;margin-right:10px;text-align:center;}
.template_img_chooser_inner img{width:48px;height:48px}
.template_img_chooser_inner p{text-align:center;line-height:8px;}
#template_img_chooser{width:560px;height:300px;overflow-y:scroll;position:relative}
#template_img_chooser div:hover{background-color:#eee;cursor:pointer;}
#template_img_chooser{width:560px;height:300px;overflow-y:scroll;position:relative;display:grid;grid-template-columns: repeat(6, minmax(0, 1fr));}
#template_img_chooser div:hover{color:#ff8c2f;cursor:pointer;}
#form_content{display:none}
#vmform .four{overflow:hidden}
#vmform .four label{float:left;display:table-cell;width:15%;}

View File

@@ -23,14 +23,15 @@ span.advancedview_panel{display:none;line-height:16px;margin-top:1px}
.basic{display:none}
.advanced{/*Empty placeholder*/}
.switch-button-label.off{color:inherit}
.template_img_parent{position:relative}
#template_img{cursor:pointer}
#template_img:hover{opacity:0.5}
#template_img:hover i{opacity:1.0}
.template_img_chooser_inner{display:inline-block;width:80px;margin-bottom:15px;margin-right:10px;text-align:center;}
.template_img_chooser_inner img{width:48px;height:48px}
.template_img_chooser_inner p{text-align:center;line-height:8px;}
#template_img_chooser{width:560px;height:300px;overflow-y:scroll;position:relative}
#template_img_chooser div:hover{background-color:#eee;cursor:pointer;}
#template_img_chooser{width:560px;height:300px;overflow-y:scroll;position:relative;display:grid;grid-template-columns: repeat(6, minmax(0, 1fr));}
#template_img_chooser div:hover{color:#ff8c2f;cursor:pointer;}
#form_content{display:none}
#vmform .four{overflow:hidden}
#vmform .four label{float:left;display:table-cell;width:15%;}

View File

@@ -1532,7 +1532,6 @@
<table>
<tr><td></td>
<td>_(Select)_&nbsp&nbsp_(Boot Order)_</td></tr></div>
<tr>
<tr>
<td>_(Other PCI Devices)_:</td>
<td>
@@ -1557,7 +1556,6 @@
<label for="pci<?=$i?>">&nbsp&nbsp&nbsp&nbsp<input type="checkbox" name="pci[]" id="pci<?=$i?>" value="<?=htmlspecialchars($arrDev['id'])?>" <?=$extra?>/> &nbsp
<input type="number" size="5" maxlength="5" id="pciboot<?=$i?>" class="narrow pcibootorder" <?=$bootdisable?> style="width: 50px;" name="pciboot[<?=htmlspecialchars($arrDev['id'])?>]" title="_(Boot order)_" value="<?=$pciboot?>" >
<?=htmlspecialchars($arrDev['name'])?> | <?=htmlspecialchars($arrDev['type'])?> (<?=htmlspecialchars($arrDev['id'])?>)</label><br/>
<td><textarea class="xml" id="xmlpci<?=$i?>" rows=5 disabled ><?=htmlspecialchars($xml2['devices']['other'][$arrDev['id']])?></textarea></td>
<?
}
}
@@ -1567,6 +1565,7 @@
}
?>
</div>
<td><textarea class="xml" id="xmlpci<?=$i?>" rows=2 disabled ><?=htmlspecialchars($xml2['devices']['other']["allotherpci"])?></textarea></td>
</td>
</tr>

View File

@@ -18,22 +18,18 @@ Nchan="device_list,disk_load,parity_list"
<?
$keyfile = file_exists(_var($var,'luksKeyfile'));
$missing = file_exists('/var/tmp/missing.tmp');
$encrypt = false;
$spot = _var($var,'mdResyncPos',0)>0;
$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 (!isset($disk['fsType'])) continue;
if (strpos(_var($disk,'fsType'),'luks:')!==false || (_var($disk,'fsType')=='auto' && (strpos(_var($var,'defaultFsType'),'luks:')!==false || _var($disk,'luksState',0)==2 || _var($disk,'luksState',0)==3))) {
$encrypt = true;
if (_var($disk,'luksState',0)==0) $forced = true;
if (_var($disk,'luksState',0)==1) $present = true;
if (_var($disk,'luksState',0)==2) $missing = true;
if (_var($disk,'luksState',0)==3) $wrong = true;
}
if (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;
}
$encrypt = $forced || $present || $missing || $wrong;
if ($forced && ($present || $missing || $wrong)) $forced = false;
function check_encryption() {
@@ -383,7 +379,7 @@ devices.on('message', function(msg,meta) {
$.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 (!msg && $('#cancelButton').length>0 && $('#cancelButton').val()=="_(Cancel)_") {
if ((get === "") && $('#cancelButton').val()=="_(Cancel)_") {
$('#cancelButton').val("_(Done)_").prop('onclick',null).off('click').click(function(){refresh();});
$('#pauseButton').prop('disabled',true);
$('#cancelText').html('');
@@ -464,7 +460,7 @@ window.onunload = function(){
<? if (_var($var,'fsNumUnmountable',0)>0):?>
<tr><td>**<?=_('Unmountable disk'.(_var($var,'fsNumUnmountable',0)==1?'':'s').' present')?>:**<br>
<? $cache = [];
foreach ($disks as $disk) if (substr(_var($disk,'fsStatus'),0,11)=='Unmountable' || in_array(prefix(_var($disk,'name')),$cache)) {
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> &bullet; ".my_id(_var($disk,'id'))." ("._var($disk,'device').")<br>";
if (in_array(_var($disk,'name'),$pools)) $cache[] = $disk['name'];
}

View File

@@ -79,7 +79,7 @@ $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/VM",$libvirtd ? 0755 : 0644);
chmod("$docroot/webGui/system/ZFS_cache",$zfs ? 0755 : 0644);
foreach ($disks as $disk) {
@@ -1188,6 +1188,7 @@ function SleepNow() {
function sortTables() {
$('table.dashboard').each(function(){
var table = $(this);
sanitizeMultiCookie(table.prop('id'), ';', true);
var index = $.cookie(table.prop('id'));
// sorting list exists
if (index != null) {

View File

@@ -207,6 +207,12 @@ function selectDiskFsWidth() {
value: 0,
text: "<?=_('no devices')?>"
}));
} else if (($('#diskFsType').val()||'').indexOf('zfs') == -1) {
var label = (num_slots == 1) ? "device" : "devices";
$('#diskFsWidthZFS').append($('<option>', {
value: num_slots,
text: _(sprintf('%s '+label,num_slots))
}));
} else if ($('#diskFsProfileZFS').val() == '') {
var label = (num_slots == 1) ? "device" : "devices";
$('#diskFsWidthZFS').append($('<option>', {
@@ -250,14 +256,14 @@ function selectDiskFsProfile(init) {
if (($('#diskFsType').val()||'').indexOf('auto') != -1) {
$('#diskFsProfileBTRFS').prop('disabled',true).hide();
$('#diskFsProfileZFS').prop('disabled',true).hide();
$('#diskFsWidthZFS').prop('disabled',true).hide();;
$('#diskFsWidthZFS').hide();;
$('#compression').hide(t);
$('#autotrim').hide(t);
} else if (($('#diskFsType').val()||'').indexOf('btrfs') != -1) {
if (!init) $('#diskFsProfileBTRFS').prop('disabled',false);
$('#diskFsProfileBTRFS').show();
$('#diskFsProfileZFS').prop('disabled',true).hide();
$('#diskFsWidthZFS').prop('disabled',true).hide();
$('#diskFsWidthZFS').hide();;
$('#compression').show(t);
<?if (diskType('Cache')):?>
$('#autotrim').show(t);
@@ -267,10 +273,13 @@ function selectDiskFsProfile(init) {
}
<?endif;?>
} else if (($('#diskFsType').val()||'').indexOf('zfs') != -1) {
var subpool = "<?=isSubpool(_var($disk,'name'))?>";
$('#diskFsProfileBTRFS').prop('disabled',true).hide();
if (subpool.length) {
$('#diskFsType').prop('disabled',true).hide();
}
if (!init) {
$('#diskFsProfileZFS').prop('disabled',false);
$('#diskFsWidthZFS').prop('disabled',false);
}
$('#diskFsProfileZFS').show();
$('#diskFsWidthZFS').show();
@@ -279,7 +288,6 @@ function selectDiskFsProfile(init) {
if (num_slots == 2) $('#diskFsProfileZFS').val('mirror');
if (num_slots > 2) $('#diskFsProfileZFS').val('raidz1');
}
selectDiskFsWidth();
$('#compression').show(t);
<?if (diskType('Cache')):?>
$('#autotrim').show(t);
@@ -287,6 +295,8 @@ function selectDiskFsProfile(init) {
$('#autotrim').show(t);
<?endif;?>
}
selectDiskFsWidth();
$('#diskFsGroups').val(0);
}
function changeFsType() {
var fstype = ($('#diskFsType').val()||'').replace('luks:','');
@@ -601,7 +611,7 @@ _(Spinup group(s))_:
: <input type="text" name="diskSpinupGroup.<?=_var($disk,'idx',0)?>" maxlength="256" value="<?=_var($disk,'spinupGroup')?>">
<?endif;?>
<?if (diskType('Data') || isPool($tag)):?>
<?if (diskType('Data','Parity') || isPool($tag)):?>
_(Spin down delay)_:
: <select name="diskSpindownDelay.<?=_var($disk,'idx',0)?>">
<?=mk_option(_var($disk,'spindownDelay'), "-1", _('Use default'))?>
@@ -620,11 +630,13 @@ _(Spin down delay)_:
<?=mk_option(_var($disk,'spindownDelay'), "9", "9 "._('hours'))?>
</select><span id="smart_selftest" class='orange-text'></span>
<?endif;?>
<?if (diskType('Data') || isPool($tag)):?>
<?$fsTypeImmutable = _var($var,'fsState')=="Started" || (isPool($tag) && _var($disk,'state')!="NEW_ARRAY")?>
<?if (diskType('Data') || (!isSubpool($name) && _var($disk,'slots',0)==1)):?>
_(File system status)_:
: <?=_(_var($disk,'fsStatus'))?>&nbsp;
<?$fsTypeImmutable = (_var($var,'fsState')=="Stopped" && !empty(_var($disk,'uuid'))) || (_var($var,'fsState')=="Started" && _var($disk,'fsType')!='auto')?>
<?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_if($fsTypeImmutable)?>>
<?=mk_option(_var($disk,'fsType'), "auto", _('auto'))?>
@@ -641,6 +653,9 @@ _(File system type)_:
:info_file_system_help:
<?elseif (!isSubpool($name) && _var($disk,'slots',0)>1):?>
_(File system status)_:
: <?=_(_var($disk,'fsStatus'))?>&nbsp;
_(File system type)_:
: <select id="diskFsType" name="diskFsType.<?=_var($disk,'idx',0)?>" onchange="selectDiskFsProfile(false)" <?=disabled_if($fsTypeImmutable)?>>
<?=mk_option(_var($disk,'fsType'), "auto", _('auto'))?>
@@ -649,7 +664,9 @@ _(File system type)_:
<?=mk_option(_var($disk,'fsType'), "luks:zfs", _('zfs')." - "._('encrypted'))?>
<?=mk_option(_var($disk,'fsType'), "luks:btrfs", _('btrfs')." - "._('encrypted'))?>
</select>
<select id="diskFsProfileBTRFS" name="diskFsProfile.<?=_var($disk,'idx',0)?>" style="display:none" <?=disabled_if($fsTypeImmutable)?>>
_(Allocation profile)_:
: <select id="diskFsProfileBTRFS" name="diskFsProfile.<?=_var($disk,'idx',0)?>" style="display:none" <?=disabled_if($fsTypeImmutable)?>>
<?=mk_option(_var($disk,'fsProfile'),"single", _('single'))?>
<?if (_var($disk,'slots',0)>=2) echo mk_option(_var($disk,'fsProfile'),"raid0", _('raid0'))?>
<?if (_var($disk,'slots',0)>=2) echo mk_option(_var($disk,'fsProfile'),"raid1", _('raid1'))?>
@@ -668,10 +685,11 @@ _(File system type)_:
<?if (_var($disk,'slots',0)>=4) echo mk_option(_var($disk,'fsProfile'),"raidz3", _('raidz3'))?>
</select>
<select id="diskFsWidthZFS" name="diskFsWidth.<?=_var($disk,'idx',0)?>" style="display:none" <?=disabled_if($fsTypeImmutable)?>>
<input id="diskFsGroups" name="diskFsGroups.<?=_var($disk,'idx',0)?>" style="display:none" <?=disabled_if($fsTypeImmutable)?>>
</select>
<?elseif (isSubpool($name)=="special" || isSubpool($name)=="logs" || isSubpool($name)=="dedup"):?>
_(File system type)_:
: <select id="diskFsType" name="diskFsType.<?=_var($disk,'idx',0)?>" onchange="selectDiskFsProfile(false)" <?=disabled_if($fsTypeImmutable)?>>
_(Allocation profile)_:
: <select id="diskFsType" name="diskFsType.<?=_var($disk,'idx',0)?>" disabled>>
<?=mk_option(_var($disk,'fsType'), "zfs", _('zfs'))?>
</select>
<select id="diskFsProfileZFS" name="diskFsProfile.<?=_var($disk,'idx',0)?>" onchange="selectDiskFsWidth()" <?=disabled_if($fsTypeImmutable)?>>
@@ -682,8 +700,8 @@ _(File system type)_:
<select id="diskFsWidthZFS" name="diskFsWidth.<?=_var($disk,'idx',0)?>" style="display:none" <?=disabled_if($fsTypeImmutable)?>>
</select>
<?elseif (isSubpool($name)=="cache"):?>
_(File system type)_:
: <select id="diskFsType" name="diskFsType.<?=_var($disk,'idx',0)?>" onchange="selectDiskFsProfile(false)" <?=disabled_if($fsTypeImmutable)?>>
_(Allocation profile)_:
: <select id="diskFsType" name="diskFsType.<?=_var($disk,'idx',0)?>" disabled>>
<?=mk_option(_var($disk,'fsType'), "zfs", _('zfs'))?>
</select>
<select id="diskFsProfileZFS" name="diskFsProfile.<?=_var($disk,'idx',0)?>" onchange="selectDiskFsWidth()" <?=disabled_if($fsTypeImmutable)?>>
@@ -693,10 +711,6 @@ _(File system type)_:
<select id="diskFsWidthZFS" name="diskFsWidth.<?=_var($disk,'idx',0)?>" style="display:none" <?=disabled_if($fsTypeImmutable)?>>
</select>
<?elseif (isSubpool($name)=="spares"):?>
_(File system type)_:
: <select id="diskFsType" name="diskFsType.<?=_var($disk,'idx',0)?>" onchange="selectDiskFsProfile(false)" <?=disabled_if($fsTypeImmutable)?>>
<?=mk_option(_var($disk,'fsType'), "zfs", _('zfs'))?>
</select>
<?endif;?>
<?if (isSubpool($name)===false):?>
@@ -757,11 +771,10 @@ _(Critical disk utilization threshold)_ (%):
<?endif;?>
<?if (isPool($name) && strpos($name,$_tilde_)===false):?>
<?if (_var($var,'fsState')=="Stopped" || (_var($var,'fsState')=="Started" && _var($var,'startMode')!="Normal")): $erasable=true; endif;?>
<input type="button" id="eraseButton" value="_(Erase)_" onclick="eraseDisk('<?=$name?>')"<?=$erasable?'':' disabled'?>>
<input type="button" id="eraseButton" value="_(Erase Pool)_" onclick="eraseDisk('<?=$name?>')"<?=$erasable?'':' disabled'?>>
<?endif;?>
<?if (_var($var,'fsState')=="Stopped" && isPool($name)):?>
<?$empty = _var($disk,'devices',0)==0?>
<input type="button" value="_(Delete Pool)_" onclick="deletePool()"<?=$empty?'':' disabled'?>><?if (!$empty):?>_(Unassign **ALL** devices to delete this pool)_<?endif;?>
<input type="button" value="_(Delete Pool)_" onclick="deletePool()"<?=isSubpool($name)?' disabled':''?>>
<?endif;?>
</form>

View File

@@ -88,7 +88,7 @@ _(Select Proxy)_:
>
> Outgoing connections from the webgui and some system processes will use the specified http proxy. Docker container installs and updates will use the proxy, but the container itself will not, neither will any VMs.
>
> For a more comprehensive solution you might consider setting up <u><a href='https://docs.unraid.net/unraid-os/manual/security/vpn/#configuring-vpn-tunneled-access-for-system/' target='_blank'>_(VPN tunnel access for System)_</a></u>.
> For a more comprehensive solution you might consider setting up <u><a href='https://docs.unraid.net/go/configuring-vpn-tunneled-access-for-system/' target='_blank'>_(VPN tunnel access for System)_</a></u>.
:end
<p><strong>_(Outgoing Proxy)_ 1</strong></p>

View File

@@ -1032,14 +1032,13 @@ tstate['wg0'] = "<?=$check_wg0 ? 'active' : 'passive'?>";
var statistics = new NchanSubscriber('/sub/wireguard',{subscriber:'websocket'});
statistics.on('message', function(data) {
var list = [];
var rows = data.split('\0');
var list = [], n = [];
var x = 0; var vtun = '';
// get all existing tunnels
$('div[id^="block-wg"]').each(function(){list.push($(this).prop('id').split('-')[1]);});
// update active tunnels
for (var i=0,row; row=rows[i]; i++) {
var info = row.split(';');
var rows = JSON.parse(data);
for (var i=0,info; info=rows[i]; i++) {
if (info[0] != vtun) {
vtun = info[0];
// remove tunnel from inactive list
@@ -1281,7 +1280,7 @@ _(Local tunnel address IPv6)_:
</div>
</div>
_(Local endpoint)_:
: <span class="input"><input type="text" id="endpoint-wg0" name="Endpoint:0" class="subnet" value="<?=$vpn_wg0?'':_var($wg0,'Endpoint:0')?>" onchange="toLC(this);quickValidate(this);" pattern="<?=$validText?>" title="_(IP address or FQDN)_" placeholder="<?=$vpn_wg0?'(_(not used)_)':preg_replace('/^(.+?\.)[0-9a-zA-Z]+(\.(my)?unraid.net)$/','$1<hash>$2',$public)?>">:
: <span class="input"><input type="text" class="width:10%;" id="endpoint-wg0" name="Endpoint:0" class="subnet" value="<?=$vpn_wg0?'':_var($wg0,'Endpoint:0')?>" onchange="toLC(this);quickValidate(this);" pattern="<?=$validText?>" title="_(IP address or FQDN)_" placeholder="<?=$vpn_wg0?'(_(not used)_)':preg_replace('/^(.+?\.)[0-9a-zA-Z]+(\.(my)?unraid.net)$/','$1<hash>$2',$public)?>">:
<input type="number" name="gui:ListenPort:0" class="port" min="1" max="65535" value="<?=$vpn_wg0?'':_var($wg0,'ListenPort:0')?>" onchange="if(quickValidate(this)) {portRemark($(document.wg0),'wg0',this.value)}" placeholder="<?=$vpn_wg0?'':_var($netport,'wg0')?>"></span>
<span class="remark block" style="display:none">_(Remark)_: _(configure your router with port forwarding of port)_ **<span id="my-port-wg0"><?=_var($wg0,'ListenPort:0')?:_var($netport,'wg0')?></span>/_(UDP)_** _(to)_ **<?=$server?>:<?=_var($wg0,'ListenPort:0')?:_var($netport,'wg0')?>**</span><span class="upnp wg0 block"></span>
<input type="hidden" name="ListenPort:0" value=""><dl id="endpoint4-wg0" style="display:none"></dl><dl id="endpoint6-wg0" style="display:none"></dl>
@@ -1318,7 +1317,7 @@ _(Local tunnel firewall)_:
:wg_local_tunnel_firewall_help:
_(MTU size)_:
: <span class="input"><input type="number" name="MTU:0" class="trim" min="68" max="9198" value="<?=_var($wg0,'MTU:0')?>" onchange="quickValidate(this);" placeholder="(_(automatic)_)">_(bytes)_</span>
: <span class="input"><input type="number" name="MTU:0" class="trim" min="68" max="9198" value="<?=_var($wg0,'MTU:0')?>" onchange="quickValidate(this);" placeholder="(_(auto)_)">_(bytes)_</span>
:wg_mtu_size_help:
@@ -1362,7 +1361,7 @@ _(Peer type of access)_:
<?=mk_option(_var($wg0,"TYPE:$i"), "7", _("VPN tunneled access for system"),count($peer_wg0)==1?'':'disabled')?>
<?=mk_option(_var($wg0,"TYPE:$i"), "8", _("VPN tunneled access for docker"),count($peer_wg0)==1?'':'disabled')?>
</select></span>
<span id="access-type-<?=$i?>" class="access-type"></span>
<span id="access-type-<?=$i?>"</span>
<?if ($i==1):?>
> ![](<?=autov('/webGui/images/wireguard-help.png')?>)
@@ -1426,8 +1425,8 @@ _(Persistent keepalive)_:
:wg_persistent_keepalive_help:
</div>
<span class="pin">_(Data received)_: <span class="rx-wg0-<?=$i?>">0 B</span>_(Data sent)_: <span class="tx-wg0-<?=$i?>">0 B</span><br>_(Last handshake)_: <span class="hs-wg0-<?=$i?>">_(unknown)_</span></span>
</div>
<span class="pin">_(Data received)_: <span class="rx-wg0-<?=$i?>">0 B</span>_(Data sent)_: <span class="tx-wg0-<?=$i?>">0 B</span><br>_(Last handshake)_: <span class="hs-wg0-<?=$i?>">_(unknown)_</span></span>
<?endforeach;?>
&nbsp;

View File

@@ -224,7 +224,7 @@ _(Local tunnel address IPv6)_:
</div>
</div>
_(Local endpoint)_:
: <span class="input"><input type="text" id="endpoint-wgX" name="Endpoint:0" class="subnet" value="<?=$vpn_wgX?'':_var($wgX,'Endpoint:0')?>" onchange="toLC(this);quickValidate(this);" pattern="<?=$validText?>" title="_(IP address or FQDN)_" placeholder="<?=$vpn_wgX?'(_(not used)_)':preg_replace('/^(www\.).+(\.unraid.net)$/','$1<hash>$2',$public)?>">:
: <span class="input"><input type="text" class="width:10%;" id="endpoint-wgX" name="Endpoint:0" class="subnet" value="<?=$vpn_wgX?'':_var($wgX,'Endpoint:0')?>" onchange="toLC(this);quickValidate(this);" pattern="<?=$validText?>" title="_(IP address or FQDN)_" placeholder="<?=$vpn_wgX?'(_(not used)_)':preg_replace('/^(www\.).+(\.unraid.net)$/','$1<hash>$2',$public)?>">:
<input type="number" name="gui:ListenPort:0" class="port" min="1" max="65535" value="<?=$vpn_wgX?'':_var($wgX,'ListenPort:0')?>" onchange="if(quickValidate(this)) {portRemark($(document.wgX),'wgX',this.value)}" placeholder="<?=$vpn_wgX?'':_var($netport,'wgX')?>"></span>
<span class="remark block" style="display:none">_(Remark)_: _(configure your router with port forwarding of port)_ **<span id="my-port-wgX"><?=_var($wgX,'ListenPort:0')?:_var($netport,'wgX')?></span>/_(UDP)_** _(to)_ **<?=$server?>:<?=_var($wgX,'ListenPort:0')?:_var($netport,'wgX')?>**</span><span class="upnp wgX block"></span>
<input type="hidden" name="ListenPort:0" value=""><dl id="endpoint4-wgX" style="display:none"></dl><dl id="endpoint6-wgX" style="display:none"></dl>
@@ -261,7 +261,7 @@ _(Local tunnel firewall)_:
:wg_local_tunnel_firewall_help:
_(MTU size)_:
: <span class="input"><input type="number" name="MTU:0" class="trim" min="68" max="9198" value="<?=_var($wgX,'MTU:0')?>" onchange="quickValidate(this);" placeholder="(_(automatic)_)">_(bytes)_</span>
: <span class="input"><input type="number" name="MTU:0" class="trim" min="68" max="9198" value="<?=_var($wgX,'MTU:0')?>" onchange="quickValidate(this);" placeholder="(_(auto)_)">_(bytes)_</span>
:wg_mtu_size_help:
@@ -305,7 +305,7 @@ _(Peer type of access)_:
<?=mk_option(_var($wgX,"TYPE:$i"), "7", _("VPN tunneled access for system"),count($peer_wgX)==1?'':'disabled')?>
<?=mk_option(_var($wgX,"TYPE:$i"), "8", _("VPN tunneled access for docker"))?>
</select></span>
<span id="access-type-<?=$i?>" class="access-type"></span>
<span id="access-type-<?=$i?>"></span>
<?if ($i==1):?>
> ![](<?=autov('/webGui/images/wireguard-help.png')?>)
@@ -369,8 +369,8 @@ _(Persistent keepalive)_:
:wg_persistent_keepalive_help:
</div>
<span class="pin">_(Data received)_: <span class="rx-wgX-<?=$i?>">0 B</span>_(Data sent)_: <span class="tx-wgX-<?=$i?>">0 B</span><br>_(Last handshake)_: <span class="hs-wgX-<?=$i?>">_(unknown)_</span></span>
</div>
<span class="pin">_(Data received)_: <span class="rx-wgX-<?=$i?>">0 B</span>_(Data sent)_: <span class="tx-wgX-<?=$i?>">0 B</span><br>_(Last handshake)_: <span class="hs-wgX-<?=$i?>">_(unknown)_</span></span>
<?endforeach;?>
&nbsp;

View File

@@ -37,26 +37,3 @@
]]>
</Script>
</Agent>
<Agent>
<Name>Pushbullet</Name>
<Variables>
<Variable Help="The Access Token can be found [a href='https://www.pushbullet.com/account' target='_blank'] [u]here[/u].[/a]" Desc="Access Token" Default="">TOKEN</Variable>
<Variable Help="Specify the fields which are included in the title of the notification." Desc="Notification Title" Default="$SUBJECT">TITLE</Variable>
<Variable Help="Specify the fields which are included in the message body of the notification." Desc="Notification Message" Default="$DESCRIPTION">MESSAGE</Variable>
</Variables>
<Script>
<![CDATA[
#!/bin/bash
##########
{0}
##########
MESSAGE=$(echo "$MESSAGE" | sed -e 's:<br[ /]*>:\\n:gI' -e 's/<[^>]*>//g')
curl -s -k \
-X POST --header "Authorization: Bearer $TOKEN" \
--header 'Content-Type: application/json' \
-d "{\"type\": \"note\", \"title\": \"$TITLE\", \"body\": \"$MESSAGE\"}" \
https://api.pushbullet.com/v2/pushes 2>&1
]]>
</Script>
</Agent>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<Agent>
<Name>Pushbullet</Name>
<Variables>
<Variable Help="The Access Token can be found [a href='https://www.pushbullet.com/account' target='_blank'] [u]here[/u].[/a]" Desc="Access Token" Default="">TOKEN</Variable>
<Variable Help="Specify the fields which are included in the title of the notification." Desc="Notification Title" Default="$SUBJECT">TITLE</Variable>
<Variable Help="Specify the fields which are included in the message body of the notification." Desc="Notification Message" Default="$DESCRIPTION">MESSAGE</Variable>
</Variables>
<Script>
<![CDATA[
#!/bin/bash
##########
{0}
##########
MESSAGE=$(echo "$MESSAGE" | sed -e 's:<br[ /]*>:\\n:gI' -e 's/<[^>]*>//g')
curl -s -k \
-X POST --header "Authorization: Bearer $TOKEN" \
--header 'Content-Type: application/json' \
-d "{\"type\": \"note\", \"title\": \"$TITLE\", \"body\": \"$MESSAGE\"}" \
https://api.pushbullet.com/v2/pushes 2>&1
]]>
</Script>
</Agent>

View File

@@ -543,7 +543,7 @@ $theme_dark = in_array($display['theme'], ['black', 'gray']);
</div>
<? if (($twoFactorRequired && !empty($token)) || !$twoFactorRequired) { ?>
<p class="js-removeTimeout"><a href="https://docs.unraid.net/unraid-os/manual/troubleshooting#lost-root-password" target="_blank"><?=_('Password recovery')?></a></p>
<p class="js-removeTimeout"><a href="https://docs.unraid.net/go/lost-root-password/" target="_blank"><?=_('Password recovery')?></a></p>
<? } ?>
</div>

View File

@@ -582,7 +582,7 @@ function viewHistory() {
}
function flashReport() {
$.post('/webGui/include/Report.php',{cmd:'config'},function(check){
if (check>0) addBannerWarning("<?=_('Your flash drive is corrupted or offline').'. '._('Post your diagnostics in the forum for help').'.'?> <a target='_blank' href='https://docs.unraid.net/unraid-os/manual/changing-the-flash-device'><?=_('See also here')?></a>");
if (check>0) addBannerWarning("<?=_('Your flash drive is corrupted or offline').'. '._('Post your diagnostics in the forum for help').'.'?> <a target='_blank' href='https://docs.unraid.net/go/changing-the-flash-device/'><?=_('See also here')?></a>");
});
}
$(function() {
@@ -803,7 +803,7 @@ default:
}
echo "</span></span><span id='countdown'></span><span id='user-notice' class='red-text'></span>";
echo "<span id='copyright'>Unraid&reg; webGui &copy;2024, Lime Technology, Inc.";
echo " <a href='https://docs.unraid.net/category/manual' target='_blank' title=\""._('Online manual')."\"><i class='fa fa-book'></i> "._('manual')."</a>";
echo " <a href='https://docs.unraid.net/go/manual/' target='_blank' title=\""._('Online manual')."\"><i class='fa fa-book'></i> "._('manual')."</a>";
echo "</span></div>";
?>
<script>

View File

@@ -50,7 +50,7 @@ $match = $_POST['match'];
$checkbox = $_POST['multiSelect']=='true' ? "<input type='checkbox'>" : "";
/* Excluded folders to not show in the dropdown in the '/mnt/' directory only. */
$excludedFolders = ["RecycleBin", "addons", "disks", "remotes", "rootshare", "user0"];
$excludedFolders = ["RecycleBin", "addons", "remotes", "rootshare", "user0"];
echo "<ul class='jqueryFileTree'>";
if ($_POST['show_parent']=='true' && is_top($rootdir)) echo "<li class='directory collapsed'>$checkbox<a href='#' rel=\"".htmlspecialchars(dirname($rootdir))."\">..</a></li>";

View File

@@ -128,6 +128,9 @@ function no_tilde($name) {
function prefix($key) {
return preg_replace('/\d+$/','',$key);
}
function pool_name($key) {
return preg_replace('/(\d+$|~.*$)/', '', $key);
}
function native($name, $full=0) {
global $_tilde_, $_arrow_;
switch ($full) {

View File

@@ -119,12 +119,12 @@ function assignment(&$disk) {
function vfs_luks($fs) {
return str_starts_with($fs,'luks:');
}
function vfs_type(&$disk, $parent=false) {
function vfs_type(&$disk) {
global $disks, $pools, $crypto;
$fsType = _var($disk,'fsType');
$name = _var($disk,'name');
$type = ($parent || _var($disk,'type')=='Cache' && !in_array($name,$pools)) ? _var($disks[prefix($name)],'fsType') : $fsType;
$fsType = _var($disk,'fsType','');
$luks = '';
if (empty($fsType))
return $fsType;
if ($crypto) switch (_var($disk,'luksState',0)) {
case 0:
if (vfs_luks($fsType))
@@ -146,14 +146,14 @@ function vfs_type(&$disk, $parent=false) {
$luks = "<a class='info'><i class='padlock fa fa-lock red-text'></i><span>"._('Device locked: unknown error')."</span></a>";
break;
}
return $luks.str_replace('luks:','',$type);
return $luks.str_replace('luks:','',$fsType);
}
function fs_info(&$disk) {
global $display, $pools;
global $display;
$echo = [];
if (empty($disk['fsStatus']) || $disk['fsStatus']=='-') {
return (_var($disk,'type')=='Cache') ? "<td>".vfs_type($disk,true)."</td><td colspan='3'>"._('Device is part of a pool')."</td>" : "<td colspan='4'></td>";
} elseif (_var($disk,'fsStatus')=='Mounted') {
if (empty(_var($disk,'fsStatus','')))
return "<td colspan='4'></td>";
if (_var($disk,'fsStatus')=='Mounted') {
$echo[] = "<td>".vfs_type($disk)."</td>";
$echo[] = "<td>".my_scale(_var($disk,'fsSize',0)*1024,$unit,-1)." $unit</td>";
if ($display['text']%10==0) {
@@ -194,7 +194,7 @@ function array_offline(&$disk, $pool='') {
if (_var($disk,'type')=='Parity') $warning = $text;
} elseif (_var($var,'mdState')=='RECON_DISK') {
if (in_array(_var($disk,'status'),$status)) $warning = $text;
} elseif (_var($disk['status'])=='DISK_NEW') {
} elseif (_var($disk['status'])=='DISK_NEW' && _var($var,'mdResyncAction')=='clear') {
$warning = $text;
}
}
@@ -209,7 +209,9 @@ function array_offline(&$disk, $pool='') {
case 'DISK_NP_MISSING':
$echo[] = "<td>".device_info($disk,false)."<br><span class='diskinfo'><em>"._('Missing')."</em></span></td>";
$echo[] = "<td>".assignment($disk)."<em>{$disk['idSb']} - ".my_scale(_var($disk,'sizeSb',0)*1024,$unit)." $unit</em></td>";
$echo[] = "<td colspan='8'></td>";
$echo[] = "<td colspan='4'></td>";
$echo[] = "<td>".vfs_type($disk)."</td>";
$echo[] = "<td colspan='3'></td>";
break;
case 'DISK_NP_DSBL':
$echo[] = "<td>".device_info($disk,false)."</td>";
@@ -359,8 +361,9 @@ function array_slots() {
return implode($echo);
}
function cache_slots($off,$pool,$min,$slots) {
global $var;
global $var, $disks;
$off = $off && $min ? ' disabled' : '';
$off = '';
$max = _var($var,'MAX_CACHESZ');
$echo = [];
$echo[] = "<form method='POST' action='/update.htm' target='progressFrame'>";
@@ -368,10 +371,13 @@ function cache_slots($off,$pool,$min,$slots) {
$echo[] = "<input type='hidden' name='changeSlots' value='apply'>";
$echo[] = "<input type='hidden' name='poolName' value='$pool'>";
$echo[] = "<select class='narrow' name='poolSlots' onChange='devices.start();this.form.submit()'{$off}>";
if (_var($disks[$pool],'state')=='NEW_ARRAY' || str_contains(_var($diks[$pool],'state'),'NO_DEVICES')) {
$option = _('none');
$echo[] = "<option value='0'>$option</option>";
}
for ($n=$min; $n<=$max; $n++) {
$option = $n ?: _('none');
$selected = ($n==$slots) ? ' selected' : '';
$echo[] = "<option value='$n'{$selected}>$option</option>";
$echo[] = "<option value='$n'{$selected}>$n</option>";
}
$echo[] = "</select></form>";
return implode($echo);
@@ -507,7 +513,6 @@ while (true) {
} else {
foreach ($Cache as $disk) if (prefix($disk['name'])==$pool) {
$fstype = str_replace('luks:','',_var($disk,'fsType'));
if (substr(_var($Cache[$pool],'fsStatus'),0,11)=='Unmountable' && empty($disk['fsStatus'])) $disk['fsStatus'] = _var($Cache[$pool],'fsStatus');
$echo[$a][] = array_online($disk,$fstype);
}
if (strcmp($root,$pool)!=0) $Cache[$root]['devices'] += $Cache[$pool]['devices'];

View File

@@ -107,6 +107,9 @@ while (true) {
file_put_contents($log, "$timestamp|$duration|$speed|$status|$error|$action|$size\n", FILE_APPEND);
delete_file($stamps, $resync);
/* Parity check is completed. */
$echo = "";
}
}
@@ -130,7 +133,7 @@ while (true) {
$process = 2;
} elseif (exec('ps -C btrfs -o cmd=|grep -cv show') > 0) {
$process = 3;
} elseif (exec("zpool status|grep -c 'scrub in progress'") > 0) {
} elseif (exec("zpool status 2>/dev/null | grep -c 'scrub in progress'") > 0) {
$process = 4;
} else {
$process = 0;

View File

@@ -59,7 +59,7 @@ while (true) {
exec("sensors -uA 2>/dev/null|grep -Po 'fan\d_input: \K\d+'",$fans);
[$total,$free] = $memory;
$used = $total-$free;
$names = [_('Services'),_('Free')];
$names = [_('System'),_('Free')];
$bytes = $echo = [];
$hooks = array_filter(glob("/usr/local/emhttp/plugins/*/system/*",GLOB_NOSORT),function($file){return is_executable($file);});
foreach ($hooks as $hook) {

View File

@@ -73,11 +73,13 @@ while (true) {
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']*1024,$unit)."$unit / ".my_scale($vmdata['maxmem']*1024,$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[$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']."%;'>&nbsp&nbsp</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']."%;'>&nbsp&nbsp</span><span></span></div></span>";
$echo[$vmencode ]['mem'] = "<span>Mem: ".my_scale($vmdata['mem']*1024,$unit)."$unit / ".my_scale($vmdata['curmem']*1024,$unit)."$unit";
if ($vmdata['maxmem'] == $vmdata['curmem']) $echo[$vmencode ]['mem'] .="&nbsp&nbsp</span>";
else $echo[$vmencode ]['mem'] .= " / ".my_scale($vmdata['maxmem']*1024,$unit)."$unit&nbsp&nbsp</span>";
$echo[$vmencode ]['disk'] = "<span>Disk: "._("Rd").": ".my_scale($vmdata['rdrate'],$unit)."$unit/s "._("Wr").": ".my_scale($vmdata['wrrate'],$unit)."$unit/s&nbsp&nbsp</span>";
$echo[$vmencode ]['net'] = "<span>Net: "._("RX").": ".my_scale($vmdata['rxrate'],$unit)."$unit/s "._("TX").": ".my_scale($vmdata['txrate'],$unit)."$unit/s&nbsp&nbsp</span>";
}
}

View File

@@ -113,8 +113,18 @@ function maskIP($file) {
// anonymize public IPv4 addresses
$rfc1918 = "(127|10|172\.1[6-9]|172\.2[0-9]|172\.3[0-1]|192\.168)((\.[0-9]{1,3}){2,3}([/\" .]|$))";
run("sed -ri 's/([\"\[ ]){$rfc1918}/\\1@@@\\2\\3/g; s/([\"\[ ][0-9]{1,3}\.)([0-9]{1,3}\.){2}([0-9]{1,3})([/\" .]|$)/\\1XXX.XXX.\\3\\4/g; s/@@@//g' ".escapeshellarg($file)." 2>/dev/null");
// anonymize full IPv6 addresses
run("sed -ri 's/([\"\[ ]([0-9a-f]{1,4}:){4})(([0-9a-f]{1,4}:){3}|:)([0-9a-f]{1,4})([/\" .]|$)/\\1XXXX:XXXX:XXXX:\\5\\6/g' ".escapeshellarg($file)." 2>/dev/null");
$file_escaped = escapeshellarg($file);
// Anonymize IPv6 addresses without brackets
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' $file_escaped 2>/dev/null");
// Anonymize IPv6 addresses with brackets
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' $file_escaped 2>/dev/null");
// Handle any remaining edge cases, e.g., addresses with subnet masks
run("sed -ri 's/(([0-9a-f]{1,4}:){4})(([0-9a-f]{1,4}:){3}|:)([0-9a-f]{1,4})(\/[0-9]{1,3})([ .:/]|$)/\\1XXXX:XXXX:XXXX:\\5\\7/g' $file_escaped 2>/dev/null");
}
function download_url($url, $path="", $bg=false, $timeout=15) {
$ch = curl_init();

View File

@@ -19,7 +19,7 @@ $proxy_ini = '/usr/local/emhttp/state/proxy.ini';
$rnd = rand();
/* Comments to beginning of the proxy_sh file. */
$comments = "#!/bin/bash\n"."# Do not edit. This file is autogenerated by /usr/local/sbin/set_proxy.\n";
$comments = "#!/bin/bash\n"."# Do not edit. This file is autogenerated by /usr/local/emhttp/plugins/dynamix/scripts/set_proxy.\n";
/* Set verbose if command line switch is set. */
$verbose = false;

View File

@@ -7,12 +7,12 @@ CALLER="show"
# include IP addresses?
if check && [[ $1 == ip ]]; then
ip=()
for net in $bind; do
ip+=("$net#[$(show -4 dev $net)#$(show -6 dev $net)]")
IP=()
for NET in $BIND; do
IP+=("$NET#[$(echo $(show dev $NET)|xargs)]")
done
bind=${ip[@]}
BIND=${IP[@]}
fi
# return list
echo ${bind// /, }
echo ${BIND// /#}

View File

@@ -19,7 +19,7 @@ extract(parse_plugin_cfg('dynamix',true));
// cron operation
if ($argc==2 && $argv[1]=='cron') {
// trim btrfs, xfs
echo shell_exec("fstrim -va 2>/dev/null");
xfs_btrfs_trim(false);
// trim zfs
zfs_trim(false);
exit(0);
@@ -72,16 +72,24 @@ function zfs_trim($write) {
}
}
function xfs_btrfs_trim($write) {
exec("findmnt -lnt btrfs,xfs -o target,source|awk '\$2!~\"\\\\[\"{print \$1,\$2}'",$mounts);
foreach ($mounts as $mount) {
[$target,$source] = explode(' ',$mount);
if (is_hdd($source)) continue;
if ($write) write("$target: ... <i class='fa fa-spin fa-circle-o-notch'></i>\r");
$trim = exec("fstrim -v $target 2>/dev/null");
if ($write) {
if ($trim) write("$trim on $source\r","\n"); else write("\r");
} else {
if ($trim) echo("$trim on $source\n");
}
}
}
write(_("TRIM operation started")."\n","\n","\n");
// trim btrfs, xfs
exec("findmnt -lnt btrfs,xfs -o target,source|awk '\$2!~\"\\\\[\"{print \$1,\$2}'",$mounts);
foreach ($mounts as $mount) {
[$target,$source] = explode(' ',$mount);
if (is_hdd($source)) continue;
write("$target: ... <i class='fa fa-spin fa-circle-o-notch'></i>\r");
$trim = exec("fstrim -v $target 2>/dev/null");
if ($trim) write("$trim on $source\r","\n"); else write("\r");
}
xfs_btrfs_trim(true);
// trim zfs
zfs_trim(true);
write(_("Finished")."\n",'_DONE_','');

View File

@@ -64,7 +64,7 @@ if (!empty($strLoadedModules)) {
// Yah! CPU and motherboard supported and enabled in BIOS
$hvm = _('Enabled');
} else {
$hvm = '<a href="https://docs.unraid.net/unraid-os/manual/vm-management#system-preparation" target="_blank">';
$hvm = '<a href="https://docs.unraid.net/go/vm-system-preparation/" target="_blank">';
if (strpos($strCPUInfo,'vmx')===false && strpos($strCPUInfo, 'svm')===false) {
// CPU doesn't support virtualization
$hvm .= _('Not Available');
@@ -82,7 +82,7 @@ if (!empty($iommu_groups)) {
// Yah! CPU and motherboard supported and enabled in BIOS
$iommu = _('Enabled');
} else {
$iommu = '<a href="https://docs.unraid.net/unraid-os/manual/vm-management#determining-hvmiommu-hardware-support" target="_blank">';
$iommu = '<a href="https://docs.unraid.net/go/determining-hvmiommu-hardware-support/" target="_blank">';
if (strpos($strCPUInfo,'vmx')===false && strpos($strCPUInfo, 'svm')===false) {
// CPU doesn't support virtualization so iommu would be impossible
$iommu .= _('Not Available');

0
emhttp/plugins/dynamix/system/ZFS_cache Normal file → Executable file
View File

View File

@@ -58,14 +58,18 @@ if [[ -f $DOCKER_CFG ]]; then
. $DOCKER_CFG
fi
# Set storage driver appropriate for backing filesystem, override user setting
BACKINGFS=$(findmnt --output FSTYPE --noheadings $DOCKER_ROOT)
if [[ $BACKINGFS == btrfs ]]; then
DOCKER_OPTS="$DOCKER_OPTS --storage-driver=btrfs"
elif [[ $BACKINGFS == xfs ]]; then
# set storage driver to overlay2 if config value is found, otherwise fall back to native FS driver
if [[ $(awk -F'"' '/^DOCKER_BACKINGFS=/{print $2}' $DOCKER_CFG 2>/dev/null) == overlay2 ]]; then
DOCKER_OPTS="$DOCKER_OPTS --storage-driver=overlay2"
elif [[ $BACKINGFS == zfs ]]; then
DOCKER_OPTS="$DOCKER_OPTS --storage-driver=zfs"
else
BACKINGFS=$(findmnt --output FSTYPE --noheadings $DOCKER_ROOT)
if [[ $BACKINGFS == btrfs ]]; then
DOCKER_OPTS="$DOCKER_OPTS --storage-driver=btrfs"
elif [[ $BACKINGFS == xfs ]]; then
DOCKER_OPTS="$DOCKER_OPTS --storage-driver=overlay2"
elif [[ $BACKINGFS == zfs ]]; then
DOCKER_OPTS="$DOCKER_OPTS --storage-driver=zfs"
fi
fi
# Less verbose logging by default
@@ -86,6 +90,7 @@ MTU=$(ip link show $PORT | grep -Po 'mtu \K\d+')
if [[ -n $(ip -6 route show default dev $PORT) ]]; then
DOCKER0='fd17::/64'
DOCKER_OPTS="--ipv6 --fixed-cidr-v6=$DOCKER0 $DOCKER_OPTS"
IPV6_FORWARD=${IPV6_FORWARD:=accept}
# create IPv6 NAT rule for docker0
[[ -z $(ip6tables -t nat -S | grep -o "$DOCKER0") ]] && run ip6tables -t nat -A POSTROUTING -s $DOCKER0 ! -o docker0 -j MASQUERADE
else
@@ -453,6 +458,11 @@ docker_network_start(){
fi
fi
done
# create IPv6 forward accept rule
if [[ $IPV6_FORWARD == accept ]]; then
log "creating forward accept rule for IPv6 network"
ip6tables -P FORWARD ACCEPT
fi
log "Network started."
}

View File

@@ -76,11 +76,6 @@ fi
/usr/local/emhttp/webGui/scripts/notify smtp-init
/usr/local/emhttp/webGui/scripts/notify cron-init
# restore favorites
if [[ -x /usr/local/emhttp/webGui/scripts/restore_favorites ]]; then
/usr/local/emhttp/webGui/scripts/restore_favorites
fi
# start nchan monitoring -> stop all running nchan processes when no subscribers are connected
if [[ -x /usr/local/sbin/monitor_nchan ]]; then
/usr/local/sbin/monitor_nchan
@@ -177,6 +172,11 @@ for LANGUAGE in $CONFIG/plugins/lang-*.xml; do
done
shopt -u nullglob
# restore favorites
if [[ -x /usr/local/emhttp/webGui/scripts/restore_favorites ]]; then
/usr/local/emhttp/webGui/scripts/restore_favorites
fi
# Enable persistent bash history
PERSISTENT_BASH_HISTORY=$(grep "persist_bash_history" /boot/config/plugins/dynamix/dynamix.cfg 2>/dev/null | cut -d'=' -f2 | sed 's/"//g')
if [[ $PERSISTENT_BASH_HISTORY == 1 ]]; then

View File

@@ -26,7 +26,7 @@ ntpd_running(){
}
ntpd_build(){
cp $CONF- $CONF
[[ -f $CONF.orig ]] && cp $CONF.orig $CONF || cp $CONF $CONF.orig
echo "# Generated entries follow:" >>$CONF
echo "interface ignore wildcard" >>$CONF
if check && [[ -n $BIND ]]; then

58
etc/rc.d/rc.sysstat Normal file
View File

@@ -0,0 +1,58 @@
#!/bin/sh
#
# chkconfig: 12345 01 99
# description: Reset the system activity logs
#
# /etc/rc.d/rc.sysstat
# (C) 2000-2024 Sebastien Godard (sysstat <at> orange.fr)
#
### BEGIN INIT INFO
# Provides: sysstat
# Required-Start:
# Required-Stop:
# Default-Start: 1 2 3 4 5
# Default-Stop: 0 6
# Description: Reset the system activity logs
# Short-Description: Reset the system activity logs
### END INIT INFO
#@(#) sysstat-12.7.6 startup script:
#@(#) Insert a dummy record in current daily data file.
#@(#) This indicates that the counters have restarted from 0.
# Source functions library
[ -r /etc/rc.d/init.d/functions ] && . /etc/rc.d/init.d/functions
RETVAL=0
PIDFILE=/var/run/sysstat.pid
[ -z "$UID" ] && UID=`id -u`
# See how we were called.
case "$1" in
start)
[ $UID -eq 0 ] || exit 4
echo $$ > $PIDFILE || exit 1
echo -n "Calling the system activity data collector (sadc)... "
/usr/lib64/sa/sa1 --boot
[ $? -eq 0 ] || RETVAL=1
rm -f $PIDFILE
echo
;;
status)
[ -f $PIDFILE ] || RETVAL=3
;;
stop)
[ $UID -eq 0 ] || exit 4
;;
restart|reload|force-reload|condrestart|try-restart)
;;
*)
echo "Usage: sysstat {start|stop|status|restart|reload|force-reload|condrestart|try-restart}"
RETVAL=2
esac
exit ${RETVAL}