mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-31 05:35:13 +08:00
🎨 Sync 2026-10-09 01:04:17
This commit is contained in:
1 parent
eb76e89012
commit
812da7f08b
154 files changed
+10613
-3987
No files matched your search
@@ -106,7 +106,24 @@ emit() {
|
||||
fi
|
||||
}
|
||||
case "$url" in
|
||||
*api.github.com/*/commits*) emit "$(cat "$HP_T_API_COMMITS")" ;;
|
||||
*api.github.com/*/commits*)
|
||||
# Filtered by path, the way the real endpoint is. Asking for a file
|
||||
# that is not at that path is not a narrower question, it is a different
|
||||
# one: it matches no commit and comes back []. That is the whole reason
|
||||
# the in-repo path is a separate argument from the file name, and it is
|
||||
# what this branch can now catch - every list this project ships used to
|
||||
# live in the repo root, so path= and the file name were the same string
|
||||
# and nothing could tell them apart.
|
||||
case "$url" in
|
||||
*repos/MetaCubeX/*)
|
||||
case "$url" in
|
||||
*"path=geo/geoip/cn.list"*) emit "$(cat "$HP_T_API_COMMITS")" ;;
|
||||
*) emit '[]' ;;
|
||||
esac
|
||||
;;
|
||||
*) emit "$(cat "$HP_T_API_COMMITS")" ;;
|
||||
esac
|
||||
;;
|
||||
*api.github.com/*/contents*) emit "$(cat "$HP_T_API_CONTENTS")" ;;
|
||||
*)
|
||||
# A spider probe (-s) checks reachability only, and its stdout is captured
|
||||
@@ -115,6 +132,19 @@ case "$url" in
|
||||
# applet prints nothing for a probe.
|
||||
[ "$probe" = "0" ] || exit 0
|
||||
if [ -n "${HP_T_FETCH_FAIL:-}" ]; then exit 1; fi
|
||||
# The same wrong-path mistake reaches the download as a 404, and
|
||||
# pick_mirror turns that into "all mirrors unreachable" - a second
|
||||
# symptom of the one bug, reported as an unrelated-looking network
|
||||
# failure. Scoped to this source so the other lists, whose file name is
|
||||
# their in-repo path, keep resolving.
|
||||
case "$url" in
|
||||
*MetaCubeX/meta-rules-dat*)
|
||||
case "$url" in
|
||||
*geo/geoip/cn.list*) ;;
|
||||
*) exit 1 ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
emit "$(cat "$HP_T_BODY")"
|
||||
;;
|
||||
esac
|
||||
@@ -179,6 +209,21 @@ cat > "$WORK/bin/flock" <<'EOF'
|
||||
#!/bin/sh
|
||||
exit 0
|
||||
EOF
|
||||
# utpl renders firewall_post.ut into the file named by -O-less stdout; the stub
|
||||
# writes a marker line and honours a failure switch, which is all the two
|
||||
# cases below need. fw4 records that it was called and honours its own.
|
||||
cat > "$WORK/bin/utpl" <<'EOF'
|
||||
#!/bin/sh
|
||||
[ -n "${HP_T_UTPL_FAIL:-}" ] && exit 1
|
||||
printf 'rendered-from-utpl\n'
|
||||
exit 0
|
||||
EOF
|
||||
cat > "$WORK/bin/fw4" <<'EOF'
|
||||
#!/bin/sh
|
||||
[ -n "$HP_T_FW4_CALLED" ] && printf 'called\n' >> "$HP_T_FW4_CALLED"
|
||||
[ -n "${HP_T_FW4_FAIL:-}" ] && exit 1
|
||||
exit 0
|
||||
EOF
|
||||
chmod +x "$WORK/bin/"*
|
||||
|
||||
PATH="$WORK/bin:$PATH"
|
||||
@@ -205,14 +250,20 @@ EOF
|
||||
|
||||
write_contents_json() {
|
||||
# write_contents_json <blob-sha-or-empty>
|
||||
# The upstream file is cn.list, not ipv4.txt: it carries both address
|
||||
# families and each listtype takes one half of it (install_download).
|
||||
if [ -n "$1" ]; then
|
||||
printf '{"name":"ipv4.txt","size":6,"sha":"%s"}' "$1" > "$WORK/api-contents.json"
|
||||
printf '{"name":"cn.list","size":6,"sha":"%s"}' "$1" > "$WORK/api-contents.json"
|
||||
else
|
||||
printf '{"name":"ipv4.txt","size":6}' > "$WORK/api-contents.json"
|
||||
printf '{"name":"cn.list","size":6}' > "$WORK/api-contents.json"
|
||||
fi
|
||||
}
|
||||
|
||||
printf 'fresh\n' > "$WORK/body.txt"
|
||||
# Mixed on purpose: china_ip4 must end up holding only the first line, and the
|
||||
# IPv6 line is what the china_ip6 cases below split out. Keeping "fresh" as the
|
||||
# single IPv4 line means the cases that only care about the blob-id handshake
|
||||
# keep asserting on "fresh" unchanged.
|
||||
printf 'fresh\n2001:db8::/32\n' > "$WORK/body.txt"
|
||||
printf 'stale-installed-copy\n' > "$WORK/resources/china_ip4.txt"
|
||||
printf 'OLDVERSION' > "$WORK/resources/china_ip4.ver"
|
||||
|
||||
@@ -269,7 +320,7 @@ expect "the .ver is untouched" "$(cat "$WORK/resources/china_ip4.ver")" "OLDVERS
|
||||
expect "no .updated_at was written" "$([ -e "$WORK/resources/china_ip4.updated_at" ] && echo yes || echo no)" "no"
|
||||
expect "the refusal is logged with both ids" \
|
||||
"$(grep -c "does not match the content of commit $API_SHA" "$WORK/run/homeproxy-pro.log")" "1"
|
||||
expect "the downloaded copy was discarded" "$([ -e "$WORK/run/ipv4.txt" ] && echo yes || echo no)" "no"
|
||||
expect "the downloaded copy was discarded" "$([ -e "$WORK/run/cn.list" ] && echo yes || echo no)" "no"
|
||||
|
||||
echo "== case 3: no blob id from the API -> refused =="
|
||||
reset_state
|
||||
@@ -373,6 +424,109 @@ expect "the .ver is untouched" "$(cat "$WORK/resources/china_list.ver")" "OLDVER
|
||||
expect "the generator was never called" \
|
||||
"$([ -e "$HP_T_SEEN_SOURCE" ] && echo yes || echo no)" "no"
|
||||
|
||||
echo "== case 8: cn.list is split by address family =="
|
||||
# Both IP lists come out of one upstream file now (MetaCubeX cn.list), so the
|
||||
# install step splits rather than moves. What has to hold: each listtype ends
|
||||
# up at its own .txt name with only its own family in it, and the combined
|
||||
# download is not left lying in RUN_DIR for the next run to trip over.
|
||||
reset_state
|
||||
printf 'OLDVERSION' > "$WORK/resources/china_ip6.ver"
|
||||
rm -f "$WORK/resources/china_ip6.txt"
|
||||
# Set here rather than relying on the top-of-file fixture: case 6 overwrote
|
||||
# body.txt with its own domain lines.
|
||||
printf '1.0.0.0/24\n2001:db8::/32\n' > "$WORK/body.txt"
|
||||
: > "$WORK/run/homeproxy-pro.log"
|
||||
printf '%s' "$LOCAL_SHA" > "$HP_T_LOCAL_BLOB"
|
||||
rc="$("$RUN_SH" "$WORK/scripts/update_resources.sh" china_ip6 > "$WORK/stdout" 2>&1; echo $?)"
|
||||
expect "exit status 0" "$rc" "0"
|
||||
expect "china_ip6.txt was created by the split" \
|
||||
"$(cat "$WORK/resources/china_ip6.txt" 2>/dev/null)" "2001:db8::/32"
|
||||
expect "it holds no IPv4 entry" \
|
||||
"$(grep -cE '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/' "$WORK/resources/china_ip6.txt" || true)" "0"
|
||||
expect "its .ver advanced like the v4 one" \
|
||||
"$(cat "$WORK/resources/china_ip6.ver")" "2026-01-02 $API_SHA"
|
||||
expect "the combined download was cleaned out of RUN_DIR" \
|
||||
"$([ -e "$WORK/run/cn.list" ] && echo yes || echo no)" "no"
|
||||
expect "no half-written temp file survived" \
|
||||
"$([ -e "$WORK/resources/china_ip6.txt.hp-new" ] && echo yes || echo no)" "no"
|
||||
|
||||
echo "== case 9: a family with no entries is refused, not installed empty =="
|
||||
# The failure this guards is silent: an empty china_ip6.txt makes
|
||||
# firewall_post.ut count zero usable prefixes and turn v6_handled off, after
|
||||
# which every mainland IPv6 connection goes to the proxy - with no error
|
||||
# anywhere. Keeping the previous list is the only acceptable outcome.
|
||||
reset_state
|
||||
printf 'stale-v6-copy\n' > "$WORK/resources/china_ip6.txt"
|
||||
printf 'OLDVERSION' > "$WORK/resources/china_ip6.ver"
|
||||
printf 'only-v4-here/24\n' > "$WORK/body.txt"
|
||||
: > "$WORK/run/homeproxy-pro.log"
|
||||
printf '%s' "$LOCAL_SHA" > "$HP_T_LOCAL_BLOB"
|
||||
rc="$("$RUN_SH" "$WORK/scripts/update_resources.sh" china_ip6 > "$WORK/stdout" 2>&1; echo $?)"
|
||||
expect "exit status non-zero" "$rc" "1"
|
||||
expect "the previous v6 list is untouched" \
|
||||
"$(cat "$WORK/resources/china_ip6.txt")" "stale-v6-copy"
|
||||
expect "its .ver is untouched" "$(cat "$WORK/resources/china_ip6.ver")" "OLDVERSION"
|
||||
expect "the reason is logged" \
|
||||
"$(grep -c 'carries no v6 entries' "$WORK/run/homeproxy-pro.log")" "1"
|
||||
expect "no empty temp file survived" \
|
||||
"$([ -e "$WORK/resources/china_ip6.txt.hp-new" ] && echo yes || echo no)" "no"
|
||||
|
||||
echo "== case 10: a successful IP update re-renders the firewall sets =="
|
||||
# The two halves of the mainland split read the same file but go live on
|
||||
# different triggers: sing-box watches the generated rule-set, while the nft
|
||||
# set is rendered into fw4_post.nft and otherwise only a start/restart puts
|
||||
# it in place. Without this step the kernel's copy silently ages past the
|
||||
# file's, and a segment the list has since dropped keeps matching
|
||||
# `ip daddr @homeproxy_mainland_addr_v4 counter return` - which returns before
|
||||
# the redirect, so the route side never gets to correct it.
|
||||
reset_state
|
||||
printf 'v4-here/24\n2001:db8::/32\n' > "$WORK/body.txt"
|
||||
printf 'stale-rendered-ruleset\n' > "$WORK/run/fw4_post.nft"
|
||||
rm -f "$WORK/run/fw4_post.nft.new"
|
||||
export HP_T_FW4_CALLED="$WORK/fw4-called"
|
||||
rm -f "$HP_T_FW4_CALLED"
|
||||
: > "$WORK/run/homeproxy-pro.log"
|
||||
rc="$("$RUN_SH" "$WORK/scripts/update_resources.sh" china_ip4 > "$WORK/stdout" 2>&1; echo $?)"
|
||||
expect "exit status 0" "$rc" "0"
|
||||
expect "fw4_post.nft was re-rendered from the new list" \
|
||||
"$(cat "$WORK/run/fw4_post.nft" 2>/dev/null)" "rendered-from-utpl"
|
||||
expect "fw4 reload ran" \
|
||||
"$(grep -c 'called' "$HP_T_FW4_CALLED" 2>/dev/null || echo 0)" "1"
|
||||
expect "no temp file left behind" \
|
||||
"$([ -e "$WORK/run/fw4_post.nft.new" ] && echo yes || echo no)" "no"
|
||||
expect "the success is logged" \
|
||||
"$(grep -c 'Firewall mainland sets re-rendered' "$WORK/run/homeproxy-pro.log")" "1"
|
||||
|
||||
echo "== case 11: a failed render is warned about, not fatal =="
|
||||
# Failing the update would be worse than the lag it is reporting: the list on
|
||||
# disk is already the one the commit vouched for, and a resource that can
|
||||
# never refresh is a far bigger problem than one that is briefly not in the
|
||||
# firewall. The previous ruleset has to survive, or a bad render takes the
|
||||
# whole intercept layer down with it.
|
||||
reset_state
|
||||
printf 'v4-here/24\n2001:db8::/32\n' > "$WORK/body.txt"
|
||||
printf 'known-good-ruleset\n' > "$WORK/run/fw4_post.nft"
|
||||
rm -f "$WORK/run/fw4_post.nft.new"
|
||||
export HP_T_UTPL_FAIL=1
|
||||
: > "$WORK/run/homeproxy-pro.log"
|
||||
# Cleared because the point of this case is that a failed render must not
|
||||
# reach fw4 at all - inheriting case 10's record would make the assertion
|
||||
# pass for the wrong reason if the branch started reloading anyway.
|
||||
rm -f "$HP_T_FW4_CALLED"
|
||||
rc="$("$RUN_SH" "$WORK/scripts/update_resources.sh" china_ip4 > "$WORK/stdout" 2>&1; echo $?)"
|
||||
unset HP_T_UTPL_FAIL
|
||||
expect "the update still succeeded" "$rc" "0"
|
||||
expect "the list was still installed" \
|
||||
"$(cat "$WORK/resources/china_ip4.txt")" "v4-here/24"
|
||||
expect "the previous ruleset is untouched" \
|
||||
"$(cat "$WORK/run/fw4_post.nft")" "known-good-ruleset"
|
||||
expect "no half-written temp file survived" \
|
||||
"$([ -e "$WORK/run/fw4_post.nft.new" ] && echo yes || echo no)" "no"
|
||||
expect "fw4 was NOT reloaded" \
|
||||
"$(grep -c 'called' "$HP_T_FW4_CALLED" 2>/dev/null || echo 0)" "0"
|
||||
expect "the warning names the manual recovery" \
|
||||
"$(grep -c 'could not re-render fw4_post.nft' "$WORK/run/homeproxy-pro.log")" "1"
|
||||
|
||||
printf '%d checks, %d failures\n' "$CHECKS" "$FAILURES"
|
||||
if [ "$FAILED" != "0" ]; then
|
||||
echo "RESOURCE UPDATE TESTS FAILED"
|
||||
|
||||
Reference in new issue
Block a user