20260507_2 增加CCR/CIR差异定位链路
This commit is contained in:
@@ -12,20 +12,61 @@ Usage:
|
||||
[--rpki-client-bin <path>] \
|
||||
[--libtls-path <path>] \
|
||||
[--rp-run-mode <serial|parallel>] \
|
||||
[--copy-rpki-client-cache] \
|
||||
[--probe-rpki-client-cache] \
|
||||
[--ours-extra-args '<args>'] \
|
||||
[--dry-run]
|
||||
EOF
|
||||
}
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
|
||||
first_existing_executable() {
|
||||
local fallback="$1"
|
||||
shift
|
||||
local candidate
|
||||
for candidate in "$@"; do
|
||||
if [[ -x "$candidate" ]]; then
|
||||
printf '%s' "$candidate"
|
||||
return
|
||||
fi
|
||||
done
|
||||
printf '%s' "$fallback"
|
||||
}
|
||||
|
||||
first_existing_file() {
|
||||
local fallback="$1"
|
||||
shift
|
||||
local candidate
|
||||
for candidate in "$@"; do
|
||||
if [[ -f "$candidate" ]]; then
|
||||
printf '%s' "$candidate"
|
||||
return
|
||||
fi
|
||||
done
|
||||
printf '%s' "$fallback"
|
||||
}
|
||||
|
||||
RUN_ROOT=""
|
||||
REMOTE_ROOT=""
|
||||
SSH_TARGET="${SSH_TARGET:-root@47.251.56.108}"
|
||||
RPKI_CLIENT_BIN="${RPKI_CLIENT_BIN:-/home/yuyr/dev/rpki-client-9.7/build-m5/src/rpki-client}"
|
||||
LIBTLS_PATH="${LIBTLS_PATH:-/home/yuyr/dev/rpki-client-9.7/.deps/libtls/root/usr/lib/x86_64-linux-gnu/libtls.so.28.0.0}"
|
||||
RPKI_CLIENT_BIN="${RPKI_CLIENT_BIN:-$(first_existing_executable \
|
||||
"/home/yuyr/dev/rpki-client-9.7/build-m5/src/rpki-client" \
|
||||
"$ROOT_DIR/../../.cache/rpki-client-9.7-build/bin/rpki-client" \
|
||||
"$ROOT_DIR/../../.cache/rpki-client-9.7-build/src/rpki-client-9.7/src/rpki-client" \
|
||||
"$ROOT_DIR/../../.cache/rpki-client-remote9.0/rpki-client" \
|
||||
"/home/yuyr/dev/rpki-client-9.7/build-m5/src/rpki-client")}"
|
||||
LIBTLS_PATH="${LIBTLS_PATH:-$(first_existing_file \
|
||||
"/home/yuyr/dev/rpki-client-9.7/.deps/libtls/root/usr/lib/x86_64-linux-gnu/libtls.so.28.0.0" \
|
||||
"$ROOT_DIR/../../.cache/rpki-client-9.7-build/runlib/libtls.so.28" \
|
||||
"$ROOT_DIR/../../.cache/rpki-client-9.7-build/sysroot/usr/lib/x86_64-linux-gnu/libtls.so.28.0.0" \
|
||||
"$ROOT_DIR/../../.cache/rpki-client-remote9.0/libtls.so.28" \
|
||||
"/home/yuyr/dev/rpki-client-9.7/.deps/libtls/root/usr/lib/x86_64-linux-gnu/libtls.so.28.0.0")}"
|
||||
RP_RUN_MODE="${RP_RUN_MODE:-serial}"
|
||||
RIR_SET="${RIR_SET:-mixed2}"
|
||||
OURS_EXTRA_ARGS="${OURS_EXTRA_ARGS:-}"
|
||||
COPY_RPKI_CLIENT_CACHE="${COPY_RPKI_CLIENT_CACHE:-0}"
|
||||
PROBE_RPKI_CLIENT_CACHE="${PROBE_RPKI_CLIENT_CACHE:-0}"
|
||||
DRY_RUN=0
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
@@ -37,6 +78,8 @@ while [[ $# -gt 0 ]]; do
|
||||
--rpki-client-bin) RPKI_CLIENT_BIN="$2"; shift 2 ;;
|
||||
--libtls-path) LIBTLS_PATH="$2"; shift 2 ;;
|
||||
--rp-run-mode) RP_RUN_MODE="$2"; shift 2 ;;
|
||||
--copy-rpki-client-cache) COPY_RPKI_CLIENT_CACHE=1; shift ;;
|
||||
--probe-rpki-client-cache) PROBE_RPKI_CLIENT_CACHE=1; shift ;;
|
||||
--ours-extra-args) OURS_EXTRA_ARGS="$2"; shift 2 ;;
|
||||
--dry-run) DRY_RUN=1; shift ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
@@ -122,11 +165,14 @@ trap cleanup_remote EXIT
|
||||
|
||||
(
|
||||
cd "$ROOT_DIR"
|
||||
cargo build --release --bin rpki --bin ccr_to_compare_views
|
||||
cargo build --release --bin rpki --bin ccr_to_compare_views --bin ccr_state_compare --bin cir_state_compare --bin cir_probe_rpki_client_cache
|
||||
)
|
||||
|
||||
ssh "$SSH_TARGET" "set -e; id -u _rpki-client >/dev/null 2>&1 || useradd -r -M -s /usr/sbin/nologin _rpki-client || true; rm -rf '$REMOTE_ROOT'; mkdir -p '$REMOTE_ROOT/bin' '$REMOTE_ROOT/lib' '$REMOTE_ROOT/state/ours' '$REMOTE_ROOT/state/rpki-client' '$REMOTE_ROOT/steps/step-001/ours' '$REMOTE_ROOT/steps/step-001/rpki-client' '$REMOTE_ROOT/steps/step-002/ours' '$REMOTE_ROOT/steps/step-002/rpki-client'"
|
||||
ssh "$SSH_TARGET" "set -e; systemctl disable --now rpki-client.timer >/dev/null 2>&1 || true; systemctl stop rpki-client.service >/dev/null 2>&1 || true; pkill -f '[/]rpki-client([[:space:]]|$)' >/dev/null 2>&1 || true; pkill -f '[/]routinator([[:space:]]|$)' >/dev/null 2>&1 || true; id -u _rpki-client >/dev/null 2>&1 || useradd -r -M -s /usr/sbin/nologin _rpki-client || true; rm -rf '$REMOTE_ROOT'; mkdir -p '$REMOTE_ROOT/bin' '$REMOTE_ROOT/lib' '$REMOTE_ROOT/state/ours' '$REMOTE_ROOT/state/rpki-client' '$REMOTE_ROOT/steps/step-001/ours' '$REMOTE_ROOT/steps/step-001/rpki-client' '$REMOTE_ROOT/steps/step-002/ours' '$REMOTE_ROOT/steps/step-002/rpki-client'"
|
||||
scp "$ROOT_DIR/target/release/rpki" "${COPY_FILES[@]}" "$SSH_TARGET:$REMOTE_ROOT/"
|
||||
if [[ "$PROBE_RPKI_CLIENT_CACHE" == "1" ]]; then
|
||||
scp "$ROOT_DIR/target/release/cir_probe_rpki_client_cache" "$SSH_TARGET:$REMOTE_ROOT/bin/"
|
||||
fi
|
||||
scp "$RPKI_CLIENT_BIN" "$SSH_TARGET:$REMOTE_ROOT/bin/rpki-client"
|
||||
scp "$LIBTLS_PATH" "$SSH_TARGET:$REMOTE_ROOT/lib/libtls.so.28"
|
||||
printf '%s' "$OURS_EXTRA_ARGS" | ssh "$SSH_TARGET" "cat > '$REMOTE_ROOT/ours-extra-args.txt'"
|
||||
@@ -146,6 +192,8 @@ KIND="$3"
|
||||
|
||||
cd "$REMOTE_ROOT"
|
||||
mkdir -p "steps/$STEP_ID/ours" "steps/$STEP_ID/rpki-client"
|
||||
touch rpki-client-skiplist
|
||||
chmod 0644 rpki-client-skiplist
|
||||
OURS_EXTRA_ARGS="$(cat ours-extra-args.txt)"
|
||||
RP_RUN_MODE="$(cat rp-run-mode.txt)"
|
||||
RIR_SET="$(cat rir-set.txt)"
|
||||
@@ -172,6 +220,17 @@ tal_file_for_rir() {
|
||||
esac
|
||||
}
|
||||
|
||||
tal_uri_for_rir() {
|
||||
case "$1" in
|
||||
afrinic) printf '%s' "https://rpki.afrinic.net/repository/AfriNIC.cer" ;;
|
||||
apnic) printf '%s' "https://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer" ;;
|
||||
arin) printf '%s' "https://rrdp.arin.net/arin-rpki-ta.cer" ;;
|
||||
lacnic) printf '%s' "https://rrdp.lacnic.net/ta/rta-lacnic-rpki.cer" ;;
|
||||
ripe) printf '%s' "https://rpki.ripe.net/ta/ripe-ncc-ta.cer" ;;
|
||||
*) echo "unknown rir: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
ta_file_for_rir() {
|
||||
case "$1" in
|
||||
afrinic) printf '%s' "afrinic-ta.cer" ;;
|
||||
@@ -185,10 +244,13 @@ ta_file_for_rir() {
|
||||
|
||||
OURS_TAL_ARGS=()
|
||||
CLIENT_TAL_ARGS=()
|
||||
OURS_CIR_TAL_ARGS=()
|
||||
for rir in "${RIRS[@]}"; do
|
||||
tal_file="$(tal_file_for_rir "$rir")"
|
||||
ta_file="$(ta_file_for_rir "$rir")"
|
||||
tal_uri="$(tal_uri_for_rir "$rir")"
|
||||
OURS_TAL_ARGS+=(--tal-path "$tal_file" --ta-path "$ta_file")
|
||||
OURS_CIR_TAL_ARGS+=(--cir-tal-uri "$tal_uri")
|
||||
CLIENT_TAL_ARGS+=(-t "../../$tal_file")
|
||||
done
|
||||
|
||||
@@ -226,6 +288,9 @@ PY
|
||||
"${OURS_TAL_ARGS[@]}" \
|
||||
"${OURS_EXTRA_ARGV[@]}" \
|
||||
--ccr-out "steps/$STEP_ID/ours/result.ccr" \
|
||||
--cir-enable \
|
||||
--cir-out "steps/$STEP_ID/ours/result.cir" \
|
||||
"${OURS_CIR_TAL_ARGS[@]}" \
|
||||
--report-json "steps/$STEP_ID/ours/report.json" \
|
||||
> "steps/$STEP_ID/ours/run.log" 2>&1
|
||||
exit_code=$?
|
||||
@@ -268,12 +333,14 @@ PY
|
||||
set +e
|
||||
LD_LIBRARY_PATH="$REMOTE_ROOT/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" "$REMOTE_ROOT/bin/rpki-client" \
|
||||
-vv \
|
||||
-S "$REMOTE_ROOT/rpki-client-skiplist" \
|
||||
"${CLIENT_TAL_ARGS[@]}" \
|
||||
-d cache out \
|
||||
> "$REMOTE_ROOT/steps/$STEP_ID/rpki-client/run.log" 2>&1
|
||||
exit_code=$?
|
||||
set -e
|
||||
cp out/rpki.ccr "$REMOTE_ROOT/steps/$STEP_ID/rpki-client/result.ccr" 2>/dev/null || true
|
||||
cp out/rpki.cir "$REMOTE_ROOT/steps/$STEP_ID/rpki-client/result.cir" 2>/dev/null || true
|
||||
cp out/openbgpd "$REMOTE_ROOT/steps/$STEP_ID/rpki-client/openbgpd" 2>/dev/null || true
|
||||
finished_ms="$(python3 - <<'PY'
|
||||
import time
|
||||
@@ -309,26 +376,54 @@ else
|
||||
fi
|
||||
EOS
|
||||
|
||||
for rel in result.ccr round-result.json run.log stage-timing.json; do
|
||||
for rel in result.ccr result.cir round-result.json run.log stage-timing.json; do
|
||||
scp -C "$SSH_TARGET:$REMOTE_ROOT/steps/$step_id/ours/$rel" "$local_step/ours/"
|
||||
done
|
||||
for rel in result.ccr round-result.json run.log openbgpd; do
|
||||
for rel in result.ccr result.cir round-result.json run.log openbgpd; do
|
||||
scp -C "$SSH_TARGET:$REMOTE_ROOT/steps/$step_id/rpki-client/$rel" "$local_step/rpki-client/" || true
|
||||
done
|
||||
if [[ "$COPY_RPKI_CLIENT_CACHE" == "1" ]]; then
|
||||
mkdir -p "$local_step/rpki-client/cache"
|
||||
rsync -a --delete "$SSH_TARGET:$REMOTE_ROOT/state/rpki-client/cache/" "$local_step/rpki-client/cache/"
|
||||
fi
|
||||
|
||||
"$ROOT_DIR/scripts/periodic/compare_ccr_round.sh" \
|
||||
--ours-ccr "$local_step/ours/result.ccr" \
|
||||
--rpki-client-ccr "$local_step/rpki-client/result.ccr" \
|
||||
--out-dir "$local_step/compare" \
|
||||
--trust-anchor unknown >/dev/null
|
||||
if [[ -f "$local_step/ours/result.cir" && -f "$local_step/rpki-client/result.cir" ]]; then
|
||||
"$ROOT_DIR/scripts/periodic/compare_ccr_cir_round.sh" \
|
||||
--ours-ccr "$local_step/ours/result.ccr" \
|
||||
--rpki-client-ccr "$local_step/rpki-client/result.ccr" \
|
||||
--ours-cir "$local_step/ours/result.cir" \
|
||||
--rpki-client-cir "$local_step/rpki-client/result.cir" \
|
||||
--out-dir "$local_step/compare" \
|
||||
--trust-anchor unknown >/dev/null
|
||||
if [[ "$PROBE_RPKI_CLIENT_CACHE" == "1" ]]; then
|
||||
ssh "$SSH_TARGET" "set -e; mkdir -p '$REMOTE_ROOT/steps/$step_id/compare/cir'; '$REMOTE_ROOT/bin/cir_probe_rpki_client_cache' --ours-cir '$REMOTE_ROOT/steps/$step_id/ours/result.cir' --rpki-client-cir '$REMOTE_ROOT/steps/$step_id/rpki-client/result.cir' --cache-root '$REMOTE_ROOT/state/rpki-client/cache' --rpki-client-log '$REMOTE_ROOT/steps/$step_id/rpki-client/run.log' --out-json '$REMOTE_ROOT/steps/$step_id/compare/cir/rpki-client-cache-probe.json' --sample-limit 50 >/dev/null"
|
||||
scp -C "$SSH_TARGET:$REMOTE_ROOT/steps/$step_id/compare/cir/rpki-client-cache-probe.json" "$local_step/compare/cir/"
|
||||
fi
|
||||
if [[ "$COPY_RPKI_CLIENT_CACHE" == "1" ]]; then
|
||||
"$ROOT_DIR/target/release/cir_probe_rpki_client_cache" \
|
||||
--ours-cir "$local_step/ours/result.cir" \
|
||||
--rpki-client-cir "$local_step/rpki-client/result.cir" \
|
||||
--cache-root "$local_step/rpki-client/cache" \
|
||||
--rpki-client-log "$local_step/rpki-client/run.log" \
|
||||
--out-json "$local_step/compare/cir/rpki-client-cache-probe.json" \
|
||||
--sample-limit 50 >/dev/null
|
||||
fi
|
||||
else
|
||||
"$ROOT_DIR/scripts/periodic/compare_ccr_round.sh" \
|
||||
--ours-ccr "$local_step/ours/result.ccr" \
|
||||
--rpki-client-ccr "$local_step/rpki-client/result.ccr" \
|
||||
--out-dir "$local_step/compare" \
|
||||
--trust-anchor unknown >/dev/null
|
||||
fi
|
||||
|
||||
python3 - <<'PY' "$local_step/ours/round-result.json" "$local_step/rpki-client/round-result.json" "$local_step/ours/stage-timing.json" "$local_step/compare/compare-summary.json" "$local_step/step-summary.json" "$OURS_EXTRA_ARGS"
|
||||
python3 - <<'PY' "$local_step/ours/round-result.json" "$local_step/rpki-client/round-result.json" "$local_step/ours/stage-timing.json" "$local_step/compare/summary.json" "$local_step/compare/compare-summary.json" "$local_step/step-summary.json" "$OURS_EXTRA_ARGS"
|
||||
import json, sys
|
||||
ours = json.load(open(sys.argv[1]))
|
||||
client = json.load(open(sys.argv[2]))
|
||||
stage = json.load(open(sys.argv[3]))
|
||||
compare = json.load(open(sys.argv[4]))
|
||||
ours_extra_args = sys.argv[6]
|
||||
compare_path = sys.argv[4] if __import__('pathlib').Path(sys.argv[4]).exists() else sys.argv[5]
|
||||
compare = json.load(open(compare_path))
|
||||
ours_extra_args = sys.argv[7]
|
||||
json.dump(
|
||||
{
|
||||
"stepId": ours["stepId"],
|
||||
@@ -355,7 +450,7 @@ json.dump(
|
||||
"onlyInOurs": len(compare["vrps"]["onlyInOurs"]),
|
||||
"onlyInRpkiClient": len(compare["vrps"]["onlyInRpkiClient"]),
|
||||
},
|
||||
open(sys.argv[5], "w"),
|
||||
open(sys.argv[6], "w"),
|
||||
indent=2,
|
||||
)
|
||||
PY
|
||||
|
||||
188
scripts/periodic/compare_ccr_cir_round.sh
Executable file
188
scripts/periodic/compare_ccr_cir_round.sh
Executable file
@@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage:
|
||||
./scripts/periodic/compare_ccr_cir_round.sh \
|
||||
--ours-ccr <path> \
|
||||
--rpki-client-ccr <path> \
|
||||
--out-dir <path> \
|
||||
[--ours-cir <path>] \
|
||||
[--rpki-client-cir <path>] \
|
||||
[--trust-anchor <name>] \
|
||||
[--sample-limit <n>] \
|
||||
[--always-compare-cir]
|
||||
USAGE
|
||||
}
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
OURS_CCR=""
|
||||
CLIENT_CCR=""
|
||||
OURS_CIR=""
|
||||
CLIENT_CIR=""
|
||||
OUT_DIR=""
|
||||
TRUST_ANCHOR="unknown"
|
||||
SAMPLE_LIMIT="20"
|
||||
ALWAYS_COMPARE_CIR=0
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--ours-ccr) OURS_CCR="$2"; shift 2 ;;
|
||||
--rpki-client-ccr) CLIENT_CCR="$2"; shift 2 ;;
|
||||
--ours-cir) OURS_CIR="$2"; shift 2 ;;
|
||||
--rpki-client-cir) CLIENT_CIR="$2"; shift 2 ;;
|
||||
--out-dir) OUT_DIR="$2"; shift 2 ;;
|
||||
--trust-anchor) TRUST_ANCHOR="$2"; shift 2 ;;
|
||||
--sample-limit) SAMPLE_LIMIT="$2"; shift 2 ;;
|
||||
--always-compare-cir) ALWAYS_COMPARE_CIR=1; shift ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "unknown argument: $1" >&2; usage; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -n "$OURS_CCR" && -n "$CLIENT_CCR" && -n "$OUT_DIR" ]] || { usage >&2; exit 2; }
|
||||
if [[ -n "$OURS_CIR" || -n "$CLIENT_CIR" ]]; then
|
||||
[[ -n "$OURS_CIR" && -n "$CLIENT_CIR" ]] || { echo "--ours-cir and --rpki-client-cir must be provided together" >&2; exit 2; }
|
||||
fi
|
||||
|
||||
mkdir -p "$OUT_DIR/ccr"
|
||||
|
||||
"$ROOT_DIR/scripts/periodic/compare_ccr_round.sh" \
|
||||
--ours-ccr "$OURS_CCR" \
|
||||
--rpki-client-ccr "$CLIENT_CCR" \
|
||||
--out-dir "$OUT_DIR/ccr" \
|
||||
--trust-anchor "$TRUST_ANCHOR" >/dev/null
|
||||
|
||||
RUN_CIR="$(python3 - <<'PY' "$OUT_DIR/ccr/compare-summary.json" "$ALWAYS_COMPARE_CIR" "$OURS_CIR" "$CLIENT_CIR"
|
||||
import json
|
||||
import sys
|
||||
summary = json.load(open(sys.argv[1], "r", encoding="utf-8"))
|
||||
always = sys.argv[2] == "1"
|
||||
has_cir = bool(sys.argv[3]) and bool(sys.argv[4])
|
||||
ccr_match = summary.get("stateDigestMatch") is True or summary.get("allMatch") is True
|
||||
print("1" if has_cir and (always or not ccr_match) else "0")
|
||||
PY
|
||||
)"
|
||||
|
||||
if [[ "$RUN_CIR" == "1" ]]; then
|
||||
mkdir -p "$OUT_DIR/cir"
|
||||
"$ROOT_DIR/scripts/periodic/compare_cir_round.sh" \
|
||||
--ours-cir "$OURS_CIR" \
|
||||
--rpki-client-cir "$CLIENT_CIR" \
|
||||
--out-dir "$OUT_DIR/cir" \
|
||||
--sample-limit "$SAMPLE_LIMIT" >/dev/null
|
||||
fi
|
||||
|
||||
python3 - <<'PY' \
|
||||
"$OUT_DIR/ccr/compare-summary.json" \
|
||||
"$OUT_DIR/cir/cir-compare-summary.json" \
|
||||
"$OUT_DIR/summary.json" \
|
||||
"$OUT_DIR/summary.md" \
|
||||
"$ALWAYS_COMPARE_CIR" \
|
||||
"$OURS_CIR" \
|
||||
"$CLIENT_CIR" \
|
||||
"$TRUST_ANCHOR" \
|
||||
"$SAMPLE_LIMIT"
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ccr_path = Path(sys.argv[1])
|
||||
cir_path = Path(sys.argv[2])
|
||||
summary_json = Path(sys.argv[3])
|
||||
summary_md = Path(sys.argv[4])
|
||||
always_compare_cir = sys.argv[5] == "1"
|
||||
ours_cir = sys.argv[6]
|
||||
client_cir = sys.argv[7]
|
||||
trust_anchor = sys.argv[8]
|
||||
sample_limit = int(sys.argv[9])
|
||||
|
||||
ccr = json.load(open(ccr_path, "r", encoding="utf-8"))
|
||||
ccr_match = ccr.get("stateDigestMatch") is True or ccr.get("allMatch") is True
|
||||
cir_available = bool(ours_cir) and bool(client_cir)
|
||||
cir_compared = cir_path.exists()
|
||||
cir = json.load(open(cir_path, "r", encoding="utf-8")) if cir_compared else None
|
||||
|
||||
if ccr_match:
|
||||
if cir_compared and cir and cir.get("allMatch") is not True:
|
||||
diagnosis = "ccr_state_same_but_cir_process_diff"
|
||||
else:
|
||||
diagnosis = "ccr_state_digest_match"
|
||||
else:
|
||||
if not cir_available:
|
||||
diagnosis = "ccr_mismatch_cir_not_available"
|
||||
elif not cir_compared:
|
||||
diagnosis = "ccr_mismatch_cir_compare_skipped"
|
||||
elif cir.get("tals", {}).get("match") is not True:
|
||||
diagnosis = "tal_input_difference"
|
||||
elif cir.get("objects", {}).get("match") is not True:
|
||||
diagnosis = "input_object_or_manifest_accepted_set_difference"
|
||||
elif (
|
||||
cir.get("rejects", {}).get("match") is not True
|
||||
or cir.get("rejectListSha256Match") is not True
|
||||
):
|
||||
diagnosis = "validation_reject_policy_difference"
|
||||
else:
|
||||
diagnosis = "ccr_projection_sorting_encoding_or_non_cir_state_difference"
|
||||
|
||||
combined = {
|
||||
"allMatch": bool(ccr_match and (not cir_compared or (cir and cir.get("allMatch") is True))),
|
||||
"diagnosis": diagnosis,
|
||||
"comparePath": ccr.get("comparePath"),
|
||||
"stateDigestMatch": ccr_match,
|
||||
"mismatchedStates": ccr.get("mismatchedStates", []),
|
||||
"mismatchedComponents": ccr.get("mismatchedComponents", []),
|
||||
"vrps": ccr.get("vrps"),
|
||||
"vaps": ccr.get("vaps"),
|
||||
"trustAnchor": trust_anchor,
|
||||
"sampleLimit": sample_limit,
|
||||
"ccr": {
|
||||
"summaryPath": str(ccr_path),
|
||||
"stateDigestMatch": ccr_match,
|
||||
"comparePath": ccr.get("comparePath"),
|
||||
"mismatchedStates": ccr.get("mismatchedStates", []),
|
||||
"mismatchedComponents": ccr.get("mismatchedComponents", []),
|
||||
"vrpMatch": ccr.get("vrps", {}).get("match"),
|
||||
"vapMatch": ccr.get("vaps", {}).get("match"),
|
||||
},
|
||||
"cir": {
|
||||
"available": cir_available,
|
||||
"compared": cir_compared,
|
||||
"summaryPath": str(cir_path) if cir_compared else None,
|
||||
"comparePolicy": "always" if always_compare_cir else "on_ccr_mismatch",
|
||||
"allMatch": cir.get("allMatch") if cir else None,
|
||||
"objectsMatch": cir.get("objects", {}).get("match") if cir else None,
|
||||
"rejectsMatch": cir.get("rejects", {}).get("match") if cir else None,
|
||||
"talsMatch": cir.get("tals", {}).get("match") if cir else None,
|
||||
"rejectListSha256Match": cir.get("rejectListSha256Match") if cir else None,
|
||||
"oursObjectCount": cir.get("ours", {}).get("objectCount") if cir else None,
|
||||
"rpkiClientObjectCount": cir.get("rpkiClient", {}).get("objectCount") if cir else None,
|
||||
"oursRejectCount": cir.get("ours", {}).get("rejectCount") if cir else None,
|
||||
"rpkiClientRejectCount": cir.get("rpkiClient", {}).get("rejectCount") if cir else None,
|
||||
},
|
||||
}
|
||||
|
||||
summary_json.write_text(json.dumps(combined, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
|
||||
lines = [
|
||||
"# CCR/CIR Compare Summary",
|
||||
"",
|
||||
f"- `allMatch`: `{str(combined['allMatch']).lower()}`",
|
||||
f"- `diagnosis`: `{combined['diagnosis']}`",
|
||||
f"- `ccrStateDigestMatch`: `{str(ccr_match).lower()}`",
|
||||
f"- `ccrMismatchedStates`: `{','.join(combined['ccr']['mismatchedStates'])}`",
|
||||
f"- `cirCompared`: `{str(cir_compared).lower()}`",
|
||||
]
|
||||
if cir:
|
||||
lines.extend([
|
||||
f"- `cirObjectsMatch`: `{str(combined['cir']['objectsMatch']).lower()}`",
|
||||
f"- `cirRejectsMatch`: `{str(combined['cir']['rejectsMatch']).lower()}`",
|
||||
f"- `cirTalsMatch`: `{str(combined['cir']['talsMatch']).lower()}`",
|
||||
f"- `cirCounts`: ours objects `{combined['cir']['oursObjectCount']}`, rpki-client objects `{combined['cir']['rpkiClientObjectCount']}`, ours rejects `{combined['cir']['oursRejectCount']}`, rpki-client rejects `{combined['cir']['rpkiClientRejectCount']}`",
|
||||
])
|
||||
else:
|
||||
lines.append(f"- `cirSkippedReason`: `{'ccr matched' if ccr_match and not always_compare_cir else 'CIR inputs unavailable'}`")
|
||||
summary_md.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
||||
print(summary_json)
|
||||
PY
|
||||
@@ -18,6 +18,7 @@ CLIENT_CCR=""
|
||||
OUT_DIR=""
|
||||
TRUST_ANCHOR="unknown"
|
||||
CCR_TO_COMPARE_VIEWS_BIN="$ROOT_DIR/target/release/ccr_to_compare_views"
|
||||
CCR_STATE_COMPARE_BIN="$ROOT_DIR/target/release/ccr_state_compare"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
@@ -34,10 +35,10 @@ done
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
if [[ ! -x "$CCR_TO_COMPARE_VIEWS_BIN" ]]; then
|
||||
if [[ ! -x "$CCR_STATE_COMPARE_BIN" || ! -x "$CCR_TO_COMPARE_VIEWS_BIN" ]]; then
|
||||
(
|
||||
cd "$ROOT_DIR"
|
||||
cargo build --release --bin ccr_to_compare_views
|
||||
cargo build --release --bin ccr_state_compare --bin ccr_to_compare_views
|
||||
)
|
||||
fi
|
||||
|
||||
@@ -48,76 +49,13 @@ CLIENT_VAPS="$OUT_DIR/rpki-client-vaps.csv"
|
||||
SUMMARY_JSON="$OUT_DIR/compare-summary.json"
|
||||
SUMMARY_MD="$OUT_DIR/compare-summary.md"
|
||||
|
||||
"$CCR_TO_COMPARE_VIEWS_BIN" \
|
||||
--ccr "$OURS_CCR" \
|
||||
--vrps-out "$OURS_VRPS" \
|
||||
--vaps-out "$OURS_VAPS" \
|
||||
--trust-anchor "$TRUST_ANCHOR"
|
||||
|
||||
"$CCR_TO_COMPARE_VIEWS_BIN" \
|
||||
--ccr "$CLIENT_CCR" \
|
||||
--vrps-out "$CLIENT_VRPS" \
|
||||
--vaps-out "$CLIENT_VAPS" \
|
||||
--trust-anchor "$TRUST_ANCHOR"
|
||||
|
||||
python3 - <<'PY' "$OURS_VRPS" "$CLIENT_VRPS" "$OURS_VAPS" "$CLIENT_VAPS" "$SUMMARY_JSON" "$SUMMARY_MD"
|
||||
import csv
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ours_vrps_path, client_vrps_path, ours_vaps_path, client_vaps_path, json_out, md_out = sys.argv[1:]
|
||||
|
||||
|
||||
def rows(path):
|
||||
with open(path, newline="") as f:
|
||||
return list(csv.reader(f))[1:]
|
||||
|
||||
|
||||
ours_vrps = {tuple(r) for r in rows(ours_vrps_path)}
|
||||
client_vrps = {tuple(r) for r in rows(client_vrps_path)}
|
||||
ours_vaps = {tuple(r) for r in rows(ours_vaps_path)}
|
||||
client_vaps = {tuple(r) for r in rows(client_vaps_path)}
|
||||
|
||||
summary = {
|
||||
"vrps": {
|
||||
"ours": len(ours_vrps),
|
||||
"rpkiClient": len(client_vrps),
|
||||
"match": ours_vrps == client_vrps,
|
||||
"onlyInOurs": sorted(ours_vrps - client_vrps)[:20],
|
||||
"onlyInRpkiClient": sorted(client_vrps - ours_vrps)[:20],
|
||||
},
|
||||
"vaps": {
|
||||
"ours": len(ours_vaps),
|
||||
"rpkiClient": len(client_vaps),
|
||||
"match": ours_vaps == client_vaps,
|
||||
"onlyInOurs": sorted(ours_vaps - client_vaps)[:20],
|
||||
"onlyInRpkiClient": sorted(client_vaps - ours_vaps)[:20],
|
||||
},
|
||||
}
|
||||
summary["allMatch"] = summary["vrps"]["match"] and summary["vaps"]["match"]
|
||||
|
||||
Path(json_out).write_text(json.dumps(summary, indent=2), encoding="utf-8")
|
||||
|
||||
lines = [
|
||||
"# Round Compare Summary",
|
||||
"",
|
||||
f"- `allMatch`: `{summary['allMatch']}`",
|
||||
f"- `vrpMatch`: `{summary['vrps']['match']}`",
|
||||
f"- `vapMatch`: `{summary['vaps']['match']}`",
|
||||
f"- `ours_vrps`: `{summary['vrps']['ours']}`",
|
||||
f"- `rpki_client_vrps`: `{summary['vrps']['rpkiClient']}`",
|
||||
f"- `ours_vaps`: `{summary['vaps']['ours']}`",
|
||||
f"- `rpki_client_vaps`: `{summary['vaps']['rpkiClient']}`",
|
||||
"",
|
||||
"## Sample Differences",
|
||||
"",
|
||||
f"- `vrps.onlyInOurs`: `{len(summary['vrps']['onlyInOurs'])}`",
|
||||
f"- `vrps.onlyInRpkiClient`: `{len(summary['vrps']['onlyInRpkiClient'])}`",
|
||||
f"- `vaps.onlyInOurs`: `{len(summary['vaps']['onlyInOurs'])}`",
|
||||
f"- `vaps.onlyInRpkiClient`: `{len(summary['vaps']['onlyInRpkiClient'])}`",
|
||||
]
|
||||
Path(md_out).write_text("\n".join(lines) + "\n", encoding="utf-8")
|
||||
PY
|
||||
"$CCR_STATE_COMPARE_BIN" \
|
||||
--ours-ccr "$OURS_CCR" \
|
||||
--rpki-client-ccr "$CLIENT_CCR" \
|
||||
--out-json "$SUMMARY_JSON" \
|
||||
--out-md "$SUMMARY_MD" \
|
||||
--out-dir "$OUT_DIR" \
|
||||
--trust-anchor "$TRUST_ANCHOR" \
|
||||
--fallback-compare-views
|
||||
|
||||
echo "$OUT_DIR"
|
||||
|
||||
47
scripts/periodic/compare_cir_round.sh
Executable file
47
scripts/periodic/compare_cir_round.sh
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage:
|
||||
./scripts/periodic/compare_cir_round.sh \
|
||||
--ours-cir <path> \
|
||||
--rpki-client-cir <path> \
|
||||
--out-dir <path> \
|
||||
[--sample-limit <n>]
|
||||
USAGE
|
||||
}
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
OURS_CIR=""
|
||||
CLIENT_CIR=""
|
||||
OUT_DIR=""
|
||||
SAMPLE_LIMIT="20"
|
||||
CIR_STATE_COMPARE_BIN="$ROOT_DIR/target/release/cir_state_compare"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--ours-cir) OURS_CIR="$2"; shift 2 ;;
|
||||
--rpki-client-cir) CLIENT_CIR="$2"; shift 2 ;;
|
||||
--out-dir) OUT_DIR="$2"; shift 2 ;;
|
||||
--sample-limit) SAMPLE_LIMIT="$2"; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "unknown argument: $1" >&2; usage; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -n "$OURS_CIR" && -n "$CLIENT_CIR" && -n "$OUT_DIR" ]] || { usage >&2; exit 2; }
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
if [[ ! -x "$CIR_STATE_COMPARE_BIN" ]]; then
|
||||
(cd "$ROOT_DIR" && cargo build --release --bin cir_state_compare)
|
||||
fi
|
||||
|
||||
"$CIR_STATE_COMPARE_BIN" \
|
||||
--ours-cir "$OURS_CIR" \
|
||||
--rpki-client-cir "$CLIENT_CIR" \
|
||||
--out-json "$OUT_DIR/cir-compare-summary.json" \
|
||||
--out-md "$OUT_DIR/cir-compare-summary.md" \
|
||||
--sample-limit "$SAMPLE_LIMIT"
|
||||
|
||||
echo "$OUT_DIR"
|
||||
Reference in New Issue
Block a user