feat(network-tweaks): Add AdGuard Home DNS control

- Add AdGuard Home status card with enable/disable and Open UI button
- Add setAdGuardEnabled RPCD method for Docker container control
- Rename section to "DNS & Proxy Services"
- Responsive grid layout for 3 service cards

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-01-28 14:15:10 +01:00
parent dc4ec3f102
commit 4254919dd7
4 changed files with 142 additions and 6 deletions

View File

@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-network-tweaks
PKG_VERSION:=1.0.0
PKG_RELEASE:=4
PKG_RELEASE:=5
PKG_ARCH:=all
PKG_LICENSE:=Apache-2.0
PKG_MAINTAINER:=CyberMind <contact@cybermind.fr>

View File

@ -75,6 +75,13 @@ var callGetProxyStatus = rpc.declare({
expect: { }
});
var callSetAdGuardEnabled = rpc.declare({
object: 'luci.network-tweaks',
method: 'setAdGuardEnabled',
params: ['enabled'],
expect: { }
});
return view.extend({
proxyStatusData: {},
componentsData: [],
@ -239,6 +246,7 @@ return view.extend({
var proxy = this.proxyStatusData;
var cdnCache = proxy.cdn_cache || {};
var wpad = proxy.wpad || {};
var adguard = proxy.adguard_home || {};
var cdnStatusClass = cdnCache.running ? 'status-running' : 'status-stopped';
var cdnStatusText = cdnCache.running ? _('Running') : _('Stopped');
@ -249,9 +257,46 @@ return view.extend({
var wpadStatusClass = wpad.enabled ? 'status-running' : 'status-stopped';
var wpadStatusText = wpad.enabled ? _('Enabled') : _('Disabled');
var adguardStatusClass = adguard.running ? 'status-running' : 'status-stopped';
var adguardStatusText = adguard.running ? _('Running') : _('Stopped');
return E('div', { 'class': 'proxy-settings-section' }, [
E('h3', {}, _('Proxy & Caching')),
E('div', { 'class': 'proxy-grid', 'style': 'display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;' }, [
E('h3', {}, _('DNS & Proxy Services')),
E('div', { 'class': 'proxy-grid', 'style': 'display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1rem;' }, [
// AdGuard Home Card
E('div', { 'class': 'proxy-card', 'style': 'background: #16213e; border-radius: 8px; padding: 1rem; border: 1px solid #333;' }, [
E('div', { 'class': 'proxy-header', 'style': 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;' }, [
E('div', { 'style': 'display: flex; align-items: center; gap: 0.5rem;' }, [
E('span', { 'style': 'font-size: 1.5em;' }, '\ud83d\udee1\ufe0f'),
E('span', { 'style': 'font-weight: bold;' }, _('AdGuard Home'))
]),
E('span', {
'class': 'status-badge ' + adguardStatusClass,
'style': 'padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.8em; ' +
(adguard.running ? 'background: #22c55e;' : 'background: #ef4444;')
}, adguardStatusText)
]),
E('div', { 'class': 'proxy-info', 'style': 'font-size: 0.9em; color: #888; margin-bottom: 0.75rem;' }, [
E('div', {}, adguard.installed ?
_('Web UI: port ') + (adguard.port || 3000) :
_('Not installed')),
E('div', {}, adguard.installed ?
_('DNS: port ') + (adguard.dns_port || 53) :
_('Install via adguardhomectl'))
]),
E('div', { 'class': 'proxy-actions', 'style': 'display: flex; gap: 0.5rem;' }, [
E('button', {
'class': 'btn cbi-button',
'click': L.bind(this.handleAdGuardToggle, this),
'disabled': !adguard.installed
}, adguard.enabled ? _('Disable') : _('Enable')),
adguard.running ? E('a', {
'class': 'btn cbi-button',
'href': 'http://' + window.location.hostname + ':' + (adguard.port || 3000),
'target': '_blank'
}, _('Open UI')) : null
].filter(Boolean))
]),
// CDN Cache Card
E('div', { 'class': 'proxy-card', 'style': 'background: #16213e; border-radius: 8px; padding: 1rem; border: 1px solid #333;' }, [
E('div', { 'class': 'proxy-header', 'style': 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;' }, [
@ -366,6 +411,29 @@ return view.extend({
});
},
handleAdGuardToggle: function(ev) {
var currentEnabled = this.proxyStatusData.adguard_home?.enabled || false;
var newEnabled = !currentEnabled;
ui.showModal(newEnabled ? _('Starting AdGuard Home...') : _('Stopping AdGuard Home...'), [
E('p', { 'class': 'spinning' }, _('Please wait, this may take a moment...'))
]);
return callSetAdGuardEnabled(newEnabled ? 1 : 0).then(L.bind(function(result) {
ui.hideModal();
if (result.success) {
ui.addNotification(null, E('p', result.message || _('AdGuard Home updated')), 'info');
} else {
ui.addNotification(null, E('p', _('Error: ') + (result.error || 'Unknown error')), 'error');
}
// Delay refresh to allow container to start/stop
setTimeout(L.bind(this.refreshData, this), 2000);
}, this)).catch(function(err) {
ui.hideModal();
ui.addNotification(null, E('p', _('Error: ') + err.message), 'error');
});
},
renderComponentsGrid: function() {
var components = this.componentsData;

View File

@ -291,6 +291,9 @@ case "$1" in
json_close_object
json_add_object "getProxyStatus"
json_close_object
json_add_object "setAdGuardEnabled"
json_add_string "enabled" "boolean"
json_close_object
json_dump
;;
@ -579,10 +582,37 @@ EOF
;;
getProxyStatus)
# Get comprehensive proxy status (CDN Cache + WPAD)
# Get comprehensive proxy status (CDN Cache + WPAD + AdGuard Home)
json_init
json_add_boolean "success" 1
# AdGuard Home status (Docker container)
adguard_installed=0
adguard_enabled=0
adguard_running=0
adguard_port=3000
adguard_dns_port=53
if [ -x /usr/sbin/adguardhomectl ]; then
adguard_installed=1
adguard_enabled=$(uci -q get adguardhome.main.enabled || echo 0)
adguard_port=$(uci -q get adguardhome.main.port || echo 3000)
adguard_dns_port=$(uci -q get adguardhome.main.dns_port || echo 53)
# Check if container is running
if command -v docker >/dev/null 2>&1; then
docker ps --filter "name=secbx-adguardhome" --format "{{.Status}}" 2>/dev/null | grep -q "Up" && adguard_running=1
fi
fi
json_add_object "adguard_home"
json_add_boolean "installed" "$adguard_installed"
json_add_boolean "enabled" "$adguard_enabled"
json_add_boolean "running" "$adguard_running"
json_add_int "port" "$adguard_port"
json_add_int "dns_port" "$adguard_dns_port"
json_close_object
# CDN Cache status
cdn_running=0
cdn_enabled=0
@ -632,6 +662,44 @@ EOF
json_dump
;;
setAdGuardEnabled)
# Enable/disable AdGuard Home
read input
json_load "$input"
json_get_var enabled enabled
if [ ! -x /usr/sbin/adguardhomectl ]; then
json_init
json_add_boolean "success" 0
json_add_string "error" "AdGuard Home not installed"
json_dump
exit 0
fi
if [ "$enabled" = "1" ] || [ "$enabled" = "true" ]; then
uci set adguardhome.main.enabled='1'
uci commit adguardhome
/etc/init.d/adguardhome enable >/dev/null 2>&1
/etc/init.d/adguardhome start >/dev/null 2>&1 &
json_init
json_add_boolean "success" 1
json_add_string "message" "AdGuard Home enabled and starting"
else
/etc/init.d/adguardhome stop >/dev/null 2>&1
/etc/init.d/adguardhome disable >/dev/null 2>&1
uci set adguardhome.main.enabled='0'
uci commit adguardhome
json_init
json_add_boolean "success" 1
json_add_string "message" "AdGuard Home disabled"
fi
json_dump
;;
*)
json_init
json_add_boolean "success" 0

View File

@ -10,10 +10,10 @@
},
"write": {
"ubus": {
"luci.network-tweaks": ["syncNow", "setConfig", "setComponentEnabled", "setWpadEnabled"],
"luci.network-tweaks": ["syncNow", "setConfig", "setComponentEnabled", "setWpadEnabled", "setAdGuardEnabled"],
"luci.cdn-cache": ["set_enabled", "restart"]
},
"uci": ["network_tweaks", "dhcp"]
"uci": ["network_tweaks", "dhcp", "adguardhome"]
}
}
}