Skip to content

Commit c11314f

Browse files
committed
Add Performance Tweaks page for gateway optimizations (#577)
* Add Performance Tweaks UI prototype under Config Optimizer New page at /perf-tweaks with cards for fan control tuning, MongoDB SSD migration, logging offload, and SFP+ 2.5G SGMII+ patch. Includes top status area for gateway connection, udm-boot, and model detection. Supports manually-deployed mode for monitoring without management. Uses mock data for UI sign-off before backend implementation. * Fix Performance Tweaks container to match other pages' width Remove max-width constraint, use same flex column + gap pattern as SQM and Config Optimizer containers. * Fix SFP description: mention Port 7/eth6 and HSGMII synonym * Implement Performance Tweaks backend with real SSH deployment - PerfTweaksDeploymentService: status checks, deploy, remove, health checks for all 4 tweaks via SSH with delimited output parsing - Embedded resources: boot scripts from unifi-perf-tweaks repo plus the SFP+ kernel module (.ko), bundled as EmbeddedResource in csproj - Database: PerfTweakSetting table + migration for tracking manually deployed tweaks across sessions - Wire up Razor page to real service (replacing mock data) - SFP gate: checks if module already loaded before allowing deploy - MongoDB SSD: auto-deploys backup companion script alongside - SFP card: note about Port 6/eth5 support via GitHub issue - Build-time sync script (scripts/sync-perf-tweaks.ps1) to refresh embedded resources from source repo * Gate MongoDB SSD deploy on SSD volume availability Detect SSD mount (/volume1 or /volume/<uuid>/) during status check. Disable deploy button and show warning when no SSD is detected. This correctly blocks the tweak on UXG-Fiber (no internal SSD) while allowing it on UCG-Fiber and UCG-Max. * Add per-tweak gateway model compatibility filtering Each tweak now declares which gateway models it supports: - Fan Control, Logging Offload: all (UCG-Fiber, UXG-Fiber, UCG-Max) - MongoDB SSD: UCG-Fiber, UCG-Max only (UXG-Fiber has no SSD) - SFP SGMII+: UCG-Fiber, UXG-Fiber only (UCG-Max has no SFP ports) Cards are filtered per-model, and the active/total counter reflects only tweaks compatible with the detected gateway. * Fix model detection newline, proper removal procedures, audit fixes - Fix ubnt-device-info model_short missing trailing newline causing delimiter parsing to concatenate with next section - Fan control removal: restart uhwd to immediately revert PID setpoints - MongoDB SSD removal: stop services, unmount bind mount, clean up backup cron and helper scripts, restart UniFi - Journald volatile removal: restore journald.conf to persistent, uncomment syslog-ng routes, restart both services (overlay changes persist - just deleting boot script does NOT revert them) - Add syslog-ng eMMC route health check (part 2 of journald tweak) - Add IDS/IPS threat pipeline verification in journald health checks - Add qca-ssdk dependency check for SFP (pre-deploy gate + health) - Add MongoDB first-run service interruption warning - Add SFP qca-ssdk missing dependency warning in UI * Add firmware upgrade notes section from open source docs Collapsible card showing what survives UniFi Network upgrades, UniFi OS upgrades, and factory resets. Only shown when at least one tweak is active. Content sourced from the unifi-perf-tweaks prerequisites.md firmware compatibility table. * Fix syslog-ng eMMC route health check false positive, SFP alert spacing The eMMC route check was counting ALL active syslog-ng log routes (11), but most are legitimate non-eMMC routes (remote syslog, console, IDS/IPS, /dev/null). Now checks only uncommented log routes that reference destinations writing to /var/log (excluding /var/log/ulog tmpfs). Returns 0 correctly when the script has done its job. Also adds margin-top to action buttons for spacing after alert boxes. * Bump action buttons top margin to 1rem * Fix SerDes register check for padded hex format busybox devmem returns 0x00000050 (32-bit padded), not 0x50. The Contains("0x50") check fails because "0x50" isn't a contiguous substring of "0x00000050". Use EndsWith("50")/EndsWith("30") instead. * Handle manual deploys with different script names/paths - For manual deploys, downgrade file-existence health checks from Error to Ok since the user may have their own script names or paths - Detect fan control via log file existence (not just boot script name) - Runtime indicators (bind mount, journald.conf, lsmod, clock rate) are already script-name-agnostic and work for any naming convention - Create health check entries for manual tweaks even when our specific boot script filename isn't found on the gateway * Distinguish Detected vs Active status, format gateway model names Active now means deployed via our boot scripts. Detected means the tweak's runtime effects are present (module loaded, bind mount active, journald volatile) but not deployed our way. Detected state shows health checks and prompts "Mark as Manually Deployed" to opt into monitoring. Format gateway model via UniFiProductDatabase.GetProductNameFromShortname so UXG-FIBER displays as UXG-Fiber. Added missing shortname aliases (UXG-FIBER, UCG-FIBER, UCGFIBER, UCG-MAX). * Revert product DB data additions, use hyphen-stripping fallback instead GetProductNameFromShortname now tries stripping hyphens before lookup so UXG-FIBER matches existing UXGFIBER alias. No new data entries needed - leverages the existing alias mappings. * Widen health check labels to 180px, show SFP blurb for Detected state * Add note about upcoming tweaks and community ideas * Remove Config Optimizer breadcrumb * Simplify firmware upgrade table to show effective outcomes Boot scripts in /data/on_boot.d/ persist across OS upgrades and reapply all config changes on boot, so the per-component breakdown was misleading. Replaced with a 3-row scenario table showing what the user actually needs to care about. * Simplify firmware table, add temperature readout for fan control Replace per-component firmware matrix with 3-row scenario table showing effective outcomes (boot scripts handle OS upgrades automatically). Read CPU, HDD/SSD, and switch chip temperatures from hwmon sensors and display alongside fan speed in fan control health checks. * Show CPU die temp and board temps without guessed labels CPU die temp from SoC thermal zones (peak of 13 tsens sensors). Board temps from ctf2302 fan controller's 3 thermistors shown as unlabeled values - we can't map hwmon indices to specific components without the PCB layout. * Fix SFP false positive: 'not-loaded' contains 'loaded' The Contains("loaded") check matched "not-loaded" as true, causing the SFP card to show as detected on gateways where the module is not loaded. Changed to exact string comparison (Trim() == "loaded"). Also fixed qca-ssdk check and deploy pre-checks for the same bug. Renamed "Kernel Module" to "SFP Module" in health checks. * Add boot script version checking via md5sum Compute expected md5 hashes from embedded resources at startup. During status checks, md5sum each deployed boot script on the gateway and compare. When a mismatch is found, show "Boot Script: Update available" warning and an Update button on the card. Line endings normalized to LF before hashing to handle Windows/Linux differences. * Add deploy confirmation modal, firmware gating, and UX fixes Deploy confirmation: 4-checkbox modal before any deploy/update - backup completed, backup downloaded, warranty acknowledgment, risk acknowledgment. All must be checked before Confirm Deploy activates. Firmware gating: check ubnt-device-info firmware, hard block deploys above 5.1.10. Show unsupported firmware warning and disable buttons. Firmware version shown in status metrics. UX fixes: remove stale "requires module on gateway" from SFP description (we deploy it), add status-warning CSS for yellow dots, fix firmware version parsing placement in SSH command. * Add fan control note about setpoint configurability * Code review fixes: Contains false positives, modal guard, UX gaps - Fix "not-mounted".Contains("mounted") false positive for MongoDB - Fix SFP deploy verification using delimited output parsing - Server-side guard on ConfirmDeploy (check _allConfirmed + _canDeploy) - Disable SFP deploy button when qca-ssdk is missing - Include UCG-Max in page description and unsupported gateway text - Remove dead .pt-firmware-note CSS class * Fix fan control removal: write stock PID setpoints back to SDB Restarting uhwd alone does NOT clear tuned values from the SDB. The removal now writes stock defaults (cpu:100, hdd:68, rtl8372:109, rtl8261:103, standby:20) back to config.fan via the SDB Python API before restarting uhwd. Uses base64-encoded Python script to avoid shell quoting issues over SSH. * Clean up fan control log file on removal to clear Detected state * Gate fan SDB reset to UCG-Fiber/UXG-Fiber, reboot message for others Stock PID setpoints are only confirmed on UCG-Fiber and UXG-Fiber. On UCG-Max (or other models), removal removes the boot script and shows a message to reboot to restore stock fan behavior, rather than writing potentially-wrong stock values to the SDB. * Fix MongoDB SSD removal: stop UniFi first, wait for mongod, copy back Stop unifi, then unifi-mongodb (clean WiredTiger shutdown), wait for mongod to actually exit, copy SSD data back to eMMC before unmounting so next boot has current data. Previous version just deleted scripts without migrating data back. * Fix MongoDB removal: find SSD path directly instead of findmnt findmnt returns device notation (/dev/md3[/unifi-db]) not a filesystem path. Detect the SSD copy at /volume1/unifi-db or /volume/*/unifi-db directly by checking for WiredTiger file, then copy back to eMMC after unmounting. * Clean up SFP log file on removal to clear Detected state * Fix fan SDB reset model check to use normalized GatewayModel * Revert "Fix fan SDB reset model check to use normalized GatewayModel" This reverts commit 2aab6e6. * Add spinner on Remove buttons, bump deploy/remove timeout to 5 min Remove buttons now show "Removing..." spinner while operation runs. Timeout increased from 2-3 min to 5 min for both deploy and removal to handle MongoDB SSD operations (stop, copy, restart). * Disable Mark as Manually Deployed during deploy/remove operations * Fix empty deploy tooltip, fix controller terminology Render data-tooltip as null (not empty string) when deploy is allowed, so Tippy.js doesn't show an empty bubble. Still shows tooltip with reason when deploy is blocked. Changed "UniFi Network controller" to "UniFi Network" in MongoDB first-run warning. * Sync 06-mongodb-ssd-offload.sh: detect stale SSD copy on redeploy Upstream fix: compares WiredTiger timestamps between eMMC and SSD. If eMMC is newer (after a removal + eMMC writes), re-migrates instead of reusing the stale SSD data that caused unclean shutdown on redeploy. * Improve MongoDB SSD description with bulk deletion context and app responsiveness * Show 'No link' instead of 'Unknown!' for eth6 speed when no SFP plugged in * Rename 'SFP Module' to 'SFP Kernel Module' in health checks
1 parent 0568b15 commit c11314f

18 files changed

Lines changed: 4610 additions & 2 deletions

scripts/sync-perf-tweaks.ps1

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Syncs performance tweak scripts from the unifi-perf-tweaks source repo
2+
# into the NetworkOptimizer embedded resources directory.
3+
#
4+
# Run before building to pick up the latest scripts:
5+
# pwsh scripts/sync-perf-tweaks.ps1
6+
#
7+
# Source repo: https://github.com/tvancott42/unifi-perf-tweaks (private)
8+
9+
param(
10+
[string]$SourceRepo = "$env:USERPROFILE\OneDrive\PersonalProjects\OpenSource\unifi-perf-tweaks"
11+
)
12+
13+
$DestDir = Join-Path $PSScriptRoot "..\src\NetworkOptimizer.Web\Resources\PerfTweaks"
14+
15+
if (-not (Test-Path $SourceRepo)) {
16+
Write-Error "Source repo not found at: $SourceRepo"
17+
exit 1
18+
}
19+
20+
if (-not (Test-Path $DestDir)) {
21+
New-Item -ItemType Directory -Path $DestDir -Force | Out-Null
22+
}
23+
24+
$scripts = @(
25+
"scripts/06-mongodb-ssd-offload.sh",
26+
"scripts/07-mongodb-ssd-backup.sh",
27+
"scripts/10-journald-volatile.sh",
28+
"scripts/15-fan-control-tuning.sh",
29+
"scripts/20-sfp-sgmiiplus.sh"
30+
)
31+
32+
$binaries = @(
33+
"modules/force-uniphy1-sgmiiplus/force_uniphy1_sgmiiplus.ko"
34+
)
35+
36+
foreach ($file in $scripts + $binaries) {
37+
$src = Join-Path $SourceRepo $file
38+
$dest = Join-Path $DestDir (Split-Path $file -Leaf)
39+
if (Test-Path $src) {
40+
Copy-Item $src $dest -Force
41+
Write-Host " Copied: $(Split-Path $file -Leaf)"
42+
} else {
43+
Write-Warning " Missing: $file"
44+
}
45+
}
46+
47+
Write-Host "Sync complete."

0 commit comments

Comments
 (0)