- providers/zapret2/common.uc: import core.common and declare as_string helper to resolve type error during zapret2 strategy argument preparation. - service/snapshot.uc: redirect command output to /dev/null in command_success_from_args to prevent stdout leakage breaking LuCI JSON parsing on snapshot restore. - settings.js: robustly parse JSON from snapshot command output using regex delimiter. - components/action.uc: add --force-depends to opkg install arguments, detect opkg lock contention and retry with backoff, and log non-zero exit stdout as warning. - providers/nfqueue/runtime.uc: ensure standalone services are cleanly stopped and disabled before starting Tachyon-managed runtime. - section.js, generator_routes.uc, apply.uc: add community_subnets option to conditionally include community CIDRs in routing and nftables.
160 lines
8.3 KiB
Bash
160 lines
8.3 KiB
Bash
#!/usr/bin/env bash
|
|
set -eo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
TACHYON_BIN="$ROOT_DIR/tachyon/files/usr/bin/tachyon"
|
|
TACHYON_LIB="$ROOT_DIR/tachyon/files/usr/lib"
|
|
CLI_UC="$TACHYON_BIN"
|
|
LIFECYCLE_UC="$TACHYON_LIB/service/lifecycle.uc"
|
|
ZAPRET_RUNTIME="$TACHYON_LIB/providers/zapret/runtime.uc"
|
|
ZAPRET2_RUNTIME="$TACHYON_LIB/providers/zapret2/runtime.uc"
|
|
ZAPRET_COMMON="$TACHYON_LIB/providers/zapret/common.uc"
|
|
ZAPRET2_COMMON="$TACHYON_LIB/providers/zapret2/common.uc"
|
|
NFQUEUE_RUNTIME="$TACHYON_LIB/providers/nfqueue/runtime.uc"
|
|
NFQUEUE_CHECK="$TACHYON_LIB/providers/nfqueue/check.uc"
|
|
NFQUEUE_VALIDATOR="$TACHYON_LIB/providers/nfqueue/validator.uc"
|
|
ZAPRET2_CHECK="$TACHYON_LIB/providers/zapret2/check.uc"
|
|
ZAPRET2_VALIDATOR="$TACHYON_LIB/providers/zapret2/validator.uc"
|
|
|
|
fail() {
|
|
printf 'FAIL: %s\n' "$1" >&2
|
|
exit 1
|
|
}
|
|
|
|
[ ! -e "$TACHYON_LIB/zapret.sh" ] ||
|
|
fail "zapret.sh shell owner must be removed"
|
|
[ ! -e "$TACHYON_LIB/zapret2.sh" ] ||
|
|
fail "zapret2.sh shell owner must be removed"
|
|
|
|
grep -Fq '#!/usr/bin/ucode' "$TACHYON_BIN" ||
|
|
fail "tachyon entrypoint must be a direct ucode executable"
|
|
grep -Fq 'service/lifecycle.uc' "$CLI_UC" ||
|
|
fail "service/cli.uc must dispatch lifecycle orchestration through service/lifecycle.uc"
|
|
grep -Fq 'providers/zapret/runtime.uc' "$LIFECYCLE_UC" ||
|
|
fail "service/lifecycle.uc must call providers/zapret/runtime.uc"
|
|
grep -Fq 'providers/zapret2/runtime.uc' "$LIFECYCLE_UC" ||
|
|
fail "service/lifecycle.uc must call providers/zapret2/runtime.uc"
|
|
grep -Fq 'require("providers.nfqueue.runtime")' "$ZAPRET_RUNTIME" ||
|
|
fail "providers/zapret/runtime.uc must use the shared NFQUEUE runtime engine"
|
|
grep -Fq 'require("providers.nfqueue.runtime")' "$ZAPRET2_RUNTIME" ||
|
|
fail "providers/zapret2/runtime.uc must use the shared NFQUEUE runtime engine"
|
|
grep -Fq 'require("providers.zapret.common")' "$ZAPRET_RUNTIME" ||
|
|
fail "providers/zapret/runtime.uc must load zapret config"
|
|
grep -Fq 'require("providers.zapret2.common")' "$ZAPRET2_RUNTIME" ||
|
|
fail "providers/zapret2/runtime.uc must load zapret2 config"
|
|
grep -Fq 'providers/zapret/check.uc' "$ZAPRET_COMMON" ||
|
|
fail "providers/zapret/common.uc must point at its provider check wrapper"
|
|
grep -Fq 'providers/zapret2/check.uc' "$ZAPRET2_COMMON" ||
|
|
fail "providers/zapret2/common.uc must point at its provider check wrapper"
|
|
grep -Fq 'providers.zapret2.validator' "$ZAPRET2_COMMON" ||
|
|
fail "providers/zapret2/common.uc must load its provider validator"
|
|
grep -Fq 'function start_runtime' "$NFQUEUE_RUNTIME" ||
|
|
fail "providers/nfqueue/runtime.uc must own NFQUEUE start"
|
|
grep -Fq 'function stop_runtime' "$NFQUEUE_RUNTIME" ||
|
|
fail "providers/nfqueue/runtime.uc must own NFQUEUE stop"
|
|
grep -Fq 'function status_json' "$NFQUEUE_RUNTIME" ||
|
|
fail "providers/nfqueue/runtime.uc must own NFQUEUE status"
|
|
grep -Fq 'function create_nft_rules' "$NFQUEUE_RUNTIME" ||
|
|
fail "providers/nfqueue/runtime.uc must own NFQUEUE nft rules"
|
|
grep -Fq 'function validate_strategy' "$NFQUEUE_VALIDATOR" ||
|
|
fail "providers/nfqueue/validator.uc must own shared NFQUEUE strategy validation"
|
|
grep -Fq 'function nft_queue_overlap' "$NFQUEUE_CHECK" ||
|
|
fail "providers/nfqueue/check.uc must own shared NFQUEUE overlap checks"
|
|
if grep -n -E 'function (start_runtime|stop_runtime|status_json|create_nft_rules|supervisor)\b' "$ZAPRET_COMMON" "$ZAPRET2_COMMON" >/dev/null 2>&1; then
|
|
fail "provider common modules must stay thin config wrappers, not runtime engines"
|
|
fi
|
|
if grep -R -n -E 'providers/zapret/runtime\.uc" (start-runtime|stop-runtime|status|check|installed|package-installed|package-version|enabled-rule-count) zapret2' \
|
|
"$TACHYON_BIN" "$TACHYON_LIB" --include='*.sh' >/dev/null 2>&1; then
|
|
fail "zapret2 must not be multiplexed through providers/zapret/runtime.uc"
|
|
fi
|
|
if grep -R -n -E 'providers\.zapret\.|providers/zapret/' "$TACHYON_LIB/providers/zapret2" >/dev/null 2>&1; then
|
|
fail "zapret2 provider modules must not import or execute providers/zapret modules"
|
|
fi
|
|
if grep -n 'zapret2' "$ZAPRET_COMMON" >/dev/null 2>&1; then
|
|
fail "providers/zapret/common.uc must not contain zapret2 ownership"
|
|
fi
|
|
if grep -R -n -E 'start_zapret2?_runtime|stop_zapret2?_runtime|get_zapret2?_status_json|check_zapret2?_runtime_json|create_zapret2?_nft_rules|validate_rule_nfqws2?_opt|has_enabled_zapret2?_rules|get_zapret2?_rule_' \
|
|
"$TACHYON_BIN" "$TACHYON_LIB" --include='*.sh' >/dev/null 2>&1; then
|
|
fail "zapret runtime shell symbols must not remain"
|
|
fi
|
|
if grep -R -n -E 'is_zapret2?_installed|get_zapret2?_package_version' \
|
|
"$TACHYON_BIN" "$TACHYON_LIB" --include='*.sh' >/dev/null 2>&1; then
|
|
fail "zapret installed/version shell predicates must not remain"
|
|
fi
|
|
if grep -n -E 'require\("uci"\)\.cursor|uci -q|"uci", "-q"|command_output\(command_from_args\(\[ "uci"' "$NFQUEUE_RUNTIME" "$ZAPRET_COMMON" "$ZAPRET2_COMMON" >/dev/null 2>&1; then
|
|
fail "zapret provider runtimes must use core.uci instead of direct UCI cursor or CLI access"
|
|
fi
|
|
grep -Fq 'require("core.uci")' "$NFQUEUE_RUNTIME" ||
|
|
fail "providers/nfqueue/runtime.uc must use core.uci for runtime UCI access"
|
|
grep -Fq 'require("singbox.constants")' "$NFQUEUE_RUNTIME" ||
|
|
fail "providers/nfqueue/runtime.uc must share the sing-box runtime tag allocator"
|
|
grep -Fq 'runtime_constants.tag(base, postfix)' "$NFQUEUE_RUNTIME" ||
|
|
fail "providers/nfqueue/runtime.uc must allocate section tags through singbox.constants"
|
|
|
|
for mode in \
|
|
'mode == "start-runtime"' \
|
|
'mode == "stop-runtime"' \
|
|
'mode == "create-nft-rules"' \
|
|
'mode == "status"' \
|
|
'mode == "check"' \
|
|
'mode == "supervisor"'
|
|
do
|
|
grep -Fq "$mode" "$NFQUEUE_RUNTIME" ||
|
|
fail "providers/nfqueue/runtime.uc missing $mode"
|
|
done
|
|
if grep -Fq 'runtime.run("zapret", ARGV)' "$ZAPRET_RUNTIME"; then
|
|
fail "providers/zapret/runtime.uc must not carry the old hard-coded engine call"
|
|
fi
|
|
grep -Fq 'runtime.run(provider, ARGV)' "$ZAPRET_RUNTIME" ||
|
|
fail "providers/zapret/runtime.uc must be the zapret entrypoint"
|
|
grep -Fq 'require("providers.zapret2.common")' "$ZAPRET2_RUNTIME" ||
|
|
fail "providers/zapret2/runtime.uc must import providers/zapret2/common.uc"
|
|
if grep -Fq 'runtime.run("zapret2", ARGV)' "$ZAPRET2_RUNTIME"; then
|
|
fail "providers/zapret2/runtime.uc must not carry the old hard-coded engine call"
|
|
fi
|
|
grep -Fq 'runtime.run(provider, ARGV)' "$ZAPRET2_RUNTIME" ||
|
|
fail "providers/zapret2/runtime.uc must be the zapret2 entrypoint"
|
|
grep -Fq 'providers/zapret2/check.uc' "$ZAPRET2_COMMON" ||
|
|
fail "providers/zapret2/common.uc must use its own check module"
|
|
grep -Fq 'providers.zapret2.validator' "$ZAPRET2_COMMON" ||
|
|
fail "providers/zapret2/common.uc must use its own validator module"
|
|
|
|
status_json="$(TACHYON_CONFIG_NAME=tachyon-definitely-missing ucode -L "$TACHYON_LIB" "$ZAPRET_RUNTIME" status)"
|
|
JSON_VALUE="$status_json" node - <<'NODE'
|
|
const value = JSON.parse(process.env.JSON_VALUE);
|
|
if (value.configured !== false || value.enabled_rule_count !== 0 || typeof value.provider_path !== 'string') {
|
|
console.error('zapret status shape mismatch');
|
|
process.exit(1);
|
|
}
|
|
NODE
|
|
|
|
check_json="$(ucode -L "$TACHYON_LIB" "$ZAPRET2_RUNTIME" check)"
|
|
JSON_VALUE="$check_json" node - <<'NODE'
|
|
const value = JSON.parse(process.env.JSON_VALUE);
|
|
if (!Object.prototype.hasOwnProperty.call(value, 'zapret2_installed') ||
|
|
!Object.prototype.hasOwnProperty.call(value, 'zapret2_package_installed') ||
|
|
!Object.prototype.hasOwnProperty.call(value, 'zapret2_provider_path')) {
|
|
console.error('zapret2 check shape mismatch');
|
|
process.exit(1);
|
|
}
|
|
NODE
|
|
|
|
ucode -L "$TACHYON_LIB" -- "$ZAPRET2_VALIDATOR" validate-json nfqws2 '--name tachyon --intercept=1' >/dev/null ||
|
|
fail "providers/zapret2/validator.uc must validate nfqws2 strategies"
|
|
if ucode -L "$TACHYON_LIB" -- "$ZAPRET2_VALIDATOR" validate-json nfqws '--dpi-desync=fake' >/dev/null 2>&1; then
|
|
fail "providers/zapret2/validator.uc must not validate nfqws strategies"
|
|
fi
|
|
|
|
printf 'table inet x { chain y { queue num 4301 bypass } }\n' |
|
|
ucode -L "$TACHYON_LIB" "$ZAPRET2_CHECK" nft-queue-overlap TachyonTable 4300 4555 >/dev/null ||
|
|
fail "providers/zapret2/check.uc must own zapret2 queue overlap checks"
|
|
|
|
ucode -L "$TACHYON_LIB" -e '
|
|
let zapret2 = require("providers.zapret2.common");
|
|
let cfg = zapret2.config();
|
|
let args = cfg.prepare_strategy_args("--dpi-desync=fake");
|
|
if (length(args) == 0) exit(1);
|
|
' || fail "providers/zapret2/common.uc prepare_strategy_args must execute without error"
|
|
|
|
printf 'zapret runtime ownership checks passed\n'
|