feat(adguard): add AdGuard Home component with DNS modes, failover and section upstream
Add AdGuard Home as an installable Tachyon component (component card with check/update/remove/rollback/enable/disable) backed by providers/adguard (validator + runtime) and an init.d service. Backend: - action.uc: install/remove/enable/backup/rollback/dispatch/releases for 'adguard' (tar.gz from AdguardTeam/AdGuardHome, OpenWrt->AdGuard arch map) - updater.uc: adguard asset selection; updates.uc: valid_component_name and automatic update checks - runtime.uc: generates AdGuardHome.yaml from UCI (upstream=single-box DNS, fallback_dns for failover, web UI on LAN, filters), manages the daemon - dns/apply.uc: dns_main_mode (dnsmasq->AdGuard->sing-box chain, or AdGuard on :53 with dnsmasq DHCP-only) - settings: dns_main_mode (Main DNS) + dns_adguard_failover_enabled - sections: routed_dns_type/dns_type 'adguard' resolve via the AdGuard provider upstreams; validator accepts the new type - system-info: adguard_version/installed/enabled/backup fields Frontend: - component card 'AdGuard Home' with enable/disable + version actions - LuCI DNS settings tab: Main DNS selector and failover flag - section.js: AdGuard Home routed DNS protocol option Tests: tests/adguard_validator.sh, tests/adguard_runtime.sh
This commit is contained in:
@@ -53,6 +53,13 @@ const componentActionKeyMap: Record<string, UpdatesActionKey> = {
|
||||
'tailscale:install_version': 'tailscaleInstall',
|
||||
'tailscale:remove': 'tailscaleRemove',
|
||||
'tailscale:rollback': 'tailscaleRollback',
|
||||
'adguard:check_update': 'adguardCheck',
|
||||
'adguard:install': 'adguardInstall',
|
||||
'adguard:install_version': 'adguardInstall',
|
||||
'adguard:remove': 'adguardRemove',
|
||||
'adguard:rollback': 'adguardRollback',
|
||||
'adguard:enable': 'adguardEnable',
|
||||
'adguard:disable': 'adguardDisable',
|
||||
'direct_bypass:enable': 'directBypassEnable',
|
||||
'direct_bypass:disable': 'directBypassDisable',
|
||||
'torrserver_direct:enable': 'torrserverDirectEnable',
|
||||
|
||||
@@ -249,6 +249,11 @@ export interface StoreType {
|
||||
fptn_installed: number;
|
||||
fptn_backup_version?: string;
|
||||
fptn_backup_time?: number;
|
||||
adguard_version?: string;
|
||||
adguard_installed?: number;
|
||||
adguard_enabled?: number;
|
||||
adguard_backup_version?: string;
|
||||
adguard_backup_time?: number;
|
||||
server_inbounds_enabled_count: number;
|
||||
direct_bypass_enabled?: number;
|
||||
direct_bypass_address?: string;
|
||||
@@ -301,6 +306,12 @@ export interface StoreType {
|
||||
tailscaleInstall: { loading: boolean };
|
||||
tailscaleRemove: { loading: boolean };
|
||||
tailscaleRollback: { loading: boolean };
|
||||
adguardCheck: { loading: boolean };
|
||||
adguardInstall: { loading: boolean };
|
||||
adguardRemove: { loading: boolean };
|
||||
adguardRollback: { loading: boolean };
|
||||
adguardEnable: { loading: boolean };
|
||||
adguardDisable: { loading: boolean };
|
||||
directBypassEnable: { loading: boolean };
|
||||
directBypassDisable: { loading: boolean };
|
||||
torrserverDirectEnable: { loading: boolean };
|
||||
|
||||
@@ -32,6 +32,9 @@ const UNKNOWN_SYSTEM_INFO: StoreType['diagnosticsSystemInfo'] = {
|
||||
tailscale_installed: 0,
|
||||
fptn_version: _('unknown'),
|
||||
fptn_installed: 0,
|
||||
adguard_version: _('unknown'),
|
||||
adguard_installed: 0,
|
||||
adguard_enabled: 0,
|
||||
server_inbounds_enabled_count: -1,
|
||||
openwrt_version: _('unknown'),
|
||||
device_model: _('unknown'),
|
||||
|
||||
@@ -53,6 +53,12 @@ function getEmptyUpdatesActions(): StoreType['updatesActions'] {
|
||||
tailscaleInstall: { loading: false },
|
||||
tailscaleRemove: { loading: false },
|
||||
tailscaleRollback: { loading: false },
|
||||
adguardCheck: { loading: false },
|
||||
adguardInstall: { loading: false },
|
||||
adguardRemove: { loading: false },
|
||||
adguardRollback: { loading: false },
|
||||
adguardEnable: { loading: false },
|
||||
adguardDisable: { loading: false },
|
||||
directBypassEnable: { loading: false },
|
||||
directBypassDisable: { loading: false },
|
||||
torrserverDirectEnable: { loading: false },
|
||||
|
||||
@@ -207,6 +207,12 @@ export const initialDiagnosticStore: Pick<
|
||||
tailscaleInstall: { loading: false },
|
||||
tailscaleRemove: { loading: false },
|
||||
tailscaleRollback: { loading: false },
|
||||
adguardCheck: { loading: false },
|
||||
adguardInstall: { loading: false },
|
||||
adguardRemove: { loading: false },
|
||||
adguardRollback: { loading: false },
|
||||
adguardEnable: { loading: false },
|
||||
adguardDisable: { loading: false },
|
||||
directBypassEnable: { loading: false },
|
||||
directBypassDisable: { loading: false },
|
||||
torrserverDirectEnable: { loading: false },
|
||||
@@ -222,6 +228,7 @@ export const initialDiagnosticStore: Pick<
|
||||
olcrtc: { status: null, latest_version: '', release_url: '' },
|
||||
fptn: { status: null, latest_version: '', release_url: '' },
|
||||
tailscale: { status: null, latest_version: '', release_url: '' },
|
||||
adguard: { status: null, latest_version: '', release_url: '' },
|
||||
direct_bypass: { status: null, latest_version: '', release_url: '' },
|
||||
torrserver_direct: { status: null, latest_version: '', release_url: '' },
|
||||
},
|
||||
|
||||
@@ -78,6 +78,8 @@ function getComponentCardTitle(component: Tachyon.ComponentName): string {
|
||||
return 'FPTN';
|
||||
case 'tailscale':
|
||||
return 'Tailscale';
|
||||
case 'adguard':
|
||||
return 'AdGuard Home';
|
||||
default:
|
||||
return String(component);
|
||||
}
|
||||
@@ -106,6 +108,8 @@ function getComponentCurrentVersion(
|
||||
return sys.fptn_version;
|
||||
case 'tailscale':
|
||||
return sys.tailscale_version;
|
||||
case 'adguard':
|
||||
return sys.adguard_version;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
@@ -577,6 +581,23 @@ function patchSystemInfoAfterMutation(result: Tachyon.ComponentActionResult) {
|
||||
}
|
||||
}
|
||||
|
||||
if (result.component === 'adguard') {
|
||||
nextSystemInfo.providerInfoLoaded = true;
|
||||
|
||||
if (result.action === 'remove') {
|
||||
nextSystemInfo.adguard_installed = 0;
|
||||
nextSystemInfo.adguard_version = 'not installed';
|
||||
nextSystemInfo.adguard_enabled = 0;
|
||||
} else if (result.action === 'enable') {
|
||||
nextSystemInfo.adguard_enabled = 1;
|
||||
} else if (result.action === 'disable') {
|
||||
nextSystemInfo.adguard_enabled = 0;
|
||||
} else {
|
||||
nextSystemInfo.adguard_installed = 1;
|
||||
nextSystemInfo.adguard_version = version;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.component === 'direct_bypass') {
|
||||
nextSystemInfo.direct_bypass_enabled = result.action === 'enable' ? 1 : 0;
|
||||
}
|
||||
@@ -1102,6 +1123,8 @@ function getComponentInstallKey(
|
||||
return 'olcrtcInstall';
|
||||
case 'tailscale':
|
||||
return 'tailscaleInstall';
|
||||
case 'adguard':
|
||||
return 'adguardInstall';
|
||||
default:
|
||||
return 'tachyonInstall';
|
||||
}
|
||||
@@ -1151,6 +1174,8 @@ function getComponentBackupVersion(component: Tachyon.ComponentName): string {
|
||||
return sys.fptn_backup_version || '';
|
||||
case 'tailscale':
|
||||
return sys.tailscale_backup_version || '';
|
||||
case 'adguard':
|
||||
return sys.adguard_backup_version || '';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
@@ -1185,7 +1210,8 @@ function getOptionalComponentActions({
|
||||
| 'wdtt'
|
||||
| 'olcrtc'
|
||||
| 'fptn'
|
||||
| 'tailscale';
|
||||
| 'tailscale'
|
||||
| 'adguard';
|
||||
installed: boolean;
|
||||
checkKey: UpdatesActionKey;
|
||||
installKey: UpdatesActionKey;
|
||||
@@ -1225,6 +1251,7 @@ const COMPONENT_REPO_URLS: Record<Tachyon.ComponentName, string> = {
|
||||
olcrtc: 'https://github.com/Dushnilin/openwrt-olcrtc',
|
||||
fptn: 'https://github.com/Dushnilin/fptn',
|
||||
tailscale: 'https://openwrt.org/packages/pkgdata/tailscale',
|
||||
adguard: 'https://github.com/AdguardTeam/AdGuardHome',
|
||||
direct_bypass: '',
|
||||
torrserver_direct: '',
|
||||
};
|
||||
@@ -1383,6 +1410,28 @@ function getComponentCards(): ComponentCard[] {
|
||||
removeKey: 'tailscaleRemove',
|
||||
rollbackKey: 'tailscaleRollback',
|
||||
});
|
||||
const adguardInstalled = Boolean(systemInfo.adguard_installed);
|
||||
const adguardActions = [
|
||||
...getOptionalComponentActions({
|
||||
component: 'adguard',
|
||||
installed: adguardInstalled,
|
||||
checkKey: 'adguardCheck',
|
||||
installKey: 'adguardInstall',
|
||||
removeKey: 'adguardRemove',
|
||||
rollbackKey: 'adguardRollback',
|
||||
}),
|
||||
{
|
||||
key: systemInfo.adguard_enabled
|
||||
? ('adguardDisable' as UpdatesActionKey)
|
||||
: ('adguardEnable' as UpdatesActionKey),
|
||||
text: systemInfo.adguard_enabled ? _('Disable') : _('Enable'),
|
||||
icon: renderRotateCcwIcon24,
|
||||
component: 'adguard' as const,
|
||||
action: systemInfo.adguard_enabled
|
||||
? ('disable' as Tachyon.ComponentAction)
|
||||
: ('enable' as Tachyon.ComponentAction),
|
||||
},
|
||||
];
|
||||
|
||||
const directBypassEnabled = Boolean(systemInfo.direct_bypass_enabled);
|
||||
const directBypassEndpoint = systemInfo.direct_bypass_address
|
||||
@@ -1602,6 +1651,21 @@ function getComponentCards(): ComponentCard[] {
|
||||
repoUrl: COMPONENT_REPO_URLS.tailscale,
|
||||
actions: tailscaleActions,
|
||||
},
|
||||
{
|
||||
component: 'adguard',
|
||||
column: 2,
|
||||
title: 'AdGuard Home',
|
||||
version: systemInfoLoading
|
||||
? _('Loading...')
|
||||
: adguardInstalled
|
||||
? `${systemInfo.adguard_enabled ? _('Enabled') : _('Disabled')} · ${systemInfo.adguard_version || _('unknown')}`
|
||||
: _('Not installed'),
|
||||
latestVersion: getLatestVersion('adguard'),
|
||||
releaseUrl: getGitHubReleaseUrl('adguard'),
|
||||
repoUrl: COMPONENT_REPO_URLS.adguard,
|
||||
actions: adguardActions,
|
||||
supportsVersions: true,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -666,6 +666,11 @@ export namespace Tachyon {
|
||||
fptn_supported?: 0 | 1;
|
||||
fptn_backup_version?: string;
|
||||
fptn_backup_time?: number;
|
||||
adguard_version?: string;
|
||||
adguard_installed?: 0 | 1;
|
||||
adguard_enabled?: 0 | 1;
|
||||
adguard_backup_version?: string;
|
||||
adguard_backup_time?: number;
|
||||
direct_bypass_enabled?: 0 | 1;
|
||||
direct_bypass_address?: string;
|
||||
direct_bypass_port?: string;
|
||||
@@ -680,6 +685,7 @@ export namespace Tachyon {
|
||||
show_component_olcrtc?: 0 | 1;
|
||||
show_component_fptn?: 0 | 1;
|
||||
show_component_tailscale?: 0 | 1;
|
||||
show_component_adguard?: 0 | 1;
|
||||
show_component_direct_bypass?: 0 | 1;
|
||||
show_component_torrserver_direct?: 0 | 1;
|
||||
openwrt_version: string;
|
||||
@@ -702,6 +708,7 @@ export namespace Tachyon {
|
||||
zapret_installed: 0 | 1;
|
||||
zapret2_installed: 0 | 1;
|
||||
byedpi_installed: 0 | 1;
|
||||
adguard_installed?: 0 | 1;
|
||||
wdtt_installed: 0 | 1;
|
||||
olcrtc_installed: 0 | 1;
|
||||
server_inbounds_enabled_count: number;
|
||||
@@ -769,6 +776,7 @@ export namespace Tachyon {
|
||||
| 'olcrtc'
|
||||
| 'fptn'
|
||||
| 'tailscale'
|
||||
| 'adguard'
|
||||
| 'direct_bypass'
|
||||
| 'torrserver_direct';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user