Complete mapping between Service methods and the CLI commands they invoke.
Language / Idioma: English is primary. Portuguese (Brazil) translation follows the English command map.
AdGuardVpnService.runCli(args)
→ buildArgs(baseArgs, includeConnectFlags)
→ Proc.runCommand([adguardBinary, ...finalArgs])
→ strip ANSI → parse output → update properties
- Binary:
adguardvpn-cli(default, configurable viaadguardBinarysetting). buildArgs()appends-y,--no-progress, and-4/-6flags whenincludeConnectFlagsis true.- Optional systemd lifecycle: when
useSystemdServiceis enabled, only connect/disconnect operations are delegated throughsudo -n /usr/local/sbin/adguardvpn-dms-control; reads and configuration still use the configured CLI binary.
These run on recurring timers and never modify VPN state.
| Method | CLI Command | Parser | Timer |
|---|---|---|---|
checkCliAvailability() |
--version |
version string check | startup only |
refreshStatus() |
status |
parseStatusOutput() |
statusTimer |
refreshConfig() |
config show |
parseConfigOutput() |
metadataTimer |
refreshLicense() |
license |
parseLicenseOutput() |
metadataTimer |
refreshLocations() |
list-locations <count> |
parseLocationsOutput() |
locationsTimer |
These are triggered by user interaction. All timers are suspended during execution.
| Method | CLI Command | Notes |
|---|---|---|
connectFastest() |
connect -f -y --no-progress [-4|-6] |
Uses buildArgs for flags |
connectToLocation(x) |
connect -l "x" -y --no-progress [-4|-6] |
x = city, country, country name, or ISO code |
disconnect() |
disconnect |
Sets suppressReconnectOnce |
setMode(mode) |
config set-mode <tun|socks> |
— |
setProtocol(proto) |
config set-protocol <auto|http2|quic> |
— |
setUpdateChannel(ch) |
config set-update-channel <release|beta|nightly> |
— |
setDns(dns) |
config set-dns <upstream> |
— |
With systemd lifecycle enabled, the first three rows map respectively to connect-fastest, connect-location "x", and disconnect on the fixed control helper. Arguments remain separate process arguments rather than shell text.
The helper is expected to be idempotent: connect-fastest and connect-location must exit 0 without restarting the unit when the tunnel is already up on the requested target. A systemctl restart drops the interface for a few seconds and kills every in-flight connection, so an action that changes nothing must not reach systemctl. The reference implementation in scripts/adguardvpn-dms-control compares the requested target against /var/lib/adguardvpn-dms/location and accepts --force to restart anyway.
Before any connect action, prepareDisconnectedRuntime() runs a small local shell preflight:
- If the current mode is TUN and the advanced bypass is disabled,
ip -o route show to defaultis inspected. Only non-virtual default routes sharing the minimum metric are counted as conflicts. - The configured
adguardBinaryis asked todisconnectso cleanup targets the same CLI binary used by the eventual connect command. - If the AdGuard control socket exists,
lsofand thenfuserare used to detect whether another process still owns it. - If the socket is not busy, the stale socket file is removed before connecting.
The preflight returns explicit statuses used by the UI: clean, cleaned, multi-default, busy, or stale.
All CLI output goes through a pipeline:
- ANSI strip — escape sequences removed before any parsing.
- Format-specific parser — pure functions in
AdGuardVpnParsers.js. - Fallback — on parse failure, properties receive safe defaults ("Unknown", empty,
false).
| Parser | Strategy |
|---|---|
parseStatusOutput |
Regex match on connected/disconnected variants, key-value extraction |
parseConfigOutput |
Key: Value line mapping with current-config fallback for partial output |
parseLicenseOutput |
Line-by-line field extraction (email, tier, devices, renewal date) |
parseLocationsOutput |
Tries 5 column-splitting strategies in order: multi-space, tab, pipe, CSV, dashed |
| Scenario | Response |
|---|---|
| Non-zero exit code | lastError updated, error toast emitted, status refresh triggered |
| Location not found | Contextual hint: "Try refreshing locations and using the ISO code" |
| Unparseable output | Graceful fallback with "Unknown" / "No output" — no crash |
| CLI unavailable | All actions disabled, warning icon shown in bar |
Mapeamento dos métodos do Service para comandos do adguardvpn-cli.
AdGuardVpnService.runCli(args)
→ buildArgs(baseArgs, includeConnectFlags)
→ Proc.runCommand([adguardBinary, ...finalArgs])
→ remove ANSI → parser → atualiza propriedades
- Binário:
adguardvpn-clipor padrão, configurável poradguardBinary. buildArgs(): adiciona-y,--no-progresse flags-4/-6quando aplicável.- Ciclo de vida systemd opcional: com
useSystemdServiceativo, somente conexão/desconexão são delegadas porsudo -n /usr/local/sbin/adguardvpn-dms-control; leituras e configurações continuam usando o binário CLI configurado.
| Método | Comando CLI | Parser | Timer |
|---|---|---|---|
checkCliAvailability() |
--version |
checagem de versão | startup |
refreshStatus() |
status |
parseStatusOutput() |
statusTimer |
refreshConfig() |
config show |
parseConfigOutput() |
metadataTimer |
refreshLicense() |
license |
parseLicenseOutput() |
metadataTimer |
refreshLocations() |
list-locations <count> |
parseLocationsOutput() |
locationsTimer |
| Método | Comando CLI | Observação |
|---|---|---|
connectFastest() |
connect -f -y --no-progress [-4|-6] |
Usa buildArgs |
connectToLocation(x) |
connect -l "x" -y --no-progress [-4|-6] |
x = cidade, país, nome do país ou ISO |
disconnect() |
disconnect |
Seta suppressReconnectOnce |
setMode(mode) |
config set-mode <tun|socks> |
— |
setProtocol(proto) |
config set-protocol <auto|http2|quic> |
— |
setUpdateChannel(ch) |
config set-update-channel <release|beta|nightly> |
— |
setDns(dns) |
config set-dns <upstream> |
— |
Com o ciclo de vida systemd ativo, as três primeiras linhas mapeiam respectivamente para connect-fastest, connect-location "x" e disconnect no helper fixo. Os argumentos continuam separados no processo, sem interpolação em shell.
Espera-se que o helper seja idempotente: connect-fastest e connect-location devem sair com 0 sem reiniciar a unit quando o túnel já está de pé no destino pedido. Um systemctl restart derruba a interface por alguns segundos e mata toda conexão em curso, então uma ação que não muda nada não pode chegar ao systemctl. A implementação de referência em scripts/adguardvpn-dms-control compara o destino pedido com /var/lib/adguardvpn-dms/location e aceita --force para reiniciar mesmo assim.
Antes de conectar, prepareDisconnectedRuntime() executa um shell local:
- Em modo TUN, verifica rotas default com mesma menor métrica, ignorando interfaces virtuais.
- Chama
disconnectpeloadguardBinaryconfigurado. - Verifica se o socket de controle está ocupado com
lsofefuser. - Remove socket obsoleto quando não está ocupado.
Status possíveis: clean, cleaned, multi-default, busy ou stale.
Toda saída passa por remoção de ANSI, parser específico e fallback seguro. Saídas vazias ou não interpretáveis não devem quebrar a UI.
| Cenário | Resposta |
|---|---|
| Exit code não zero | Atualiza lastError, mostra toast e atualiza status |
| Localização não encontrada | Exibe dica para atualizar localizações e usar ISO quando necessário |
| Saída não interpretável | Fallback para “Unknown” / “No output” |
| CLI indisponível | Ações desabilitadas e ícone de aviso na barra |