Files
MyGoNavi/tools/verify-driver-agent-revisions.sh
Syngnat 6742495c6f 🐛 fix(frontend/ci): 修复对象修改卡顿与 Windows ARM 驱动校验失败
- QueryEditor 为对象修改标签增加 object-edit 轻量模式,跳过重型元数据抓取和对象装饰扫描
- DefinitionViewer 与 TriggerViewer 打开的对象修改标签统一透传 queryMode,避免重新进入普通查询链路
- TriggerViewer 补全 MySQL/Oracle 类触发器 DDL 重建逻辑,修复对象修改打开语法不完整
- 补充对象修改与触发器 DDL 回归测试,覆盖轻量模式和元数据补全场景
- verify-driver-agent-revisions 脚本改为跨架构校验,避免在 x64 runner 直接执行 windows/arm64 二进制
- 新增 Windows ARM CI 校验追踪文档,保留架构校验与 host-native probe 证据
2026-06-05 10:34:18 +08:00

277 lines
6.8 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$SCRIPT_DIR"
usage() {
cat <<'EOF'
用法:
./tools/verify-driver-agent-revisions.sh --assets-dir <目录> --platform <GOOS/GOARCH> --drivers <列表>
说明:
校验已构建 driver-agent 资产返回的 agentRevision 是否等于当前源码生成的 revision。
EOF
}
assets_dir=""
target_platform=""
driver_csv=""
while [[ $# -gt 0 ]]; do
case "$1" in
--assets-dir)
assets_dir="${2:-}"
shift 2
;;
--platform)
target_platform="${2:-}"
shift 2
;;
--drivers)
driver_csv="${2:-}"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
echo "未知参数:$1" >&2
usage >&2
exit 1
;;
esac
done
if [[ -z "$assets_dir" || -z "$target_platform" || -z "$driver_csv" ]]; then
usage >&2
exit 1
fi
if [[ "$target_platform" != */* ]]; then
echo "--platform 参数格式错误,应为 GOOS/GOARCH例如 darwin/arm64" >&2
exit 1
fi
goos="${target_platform%%/*}"
goarch="${target_platform##*/}"
platform_dir="Unknown"
case "$goos" in
windows) platform_dir="Windows" ;;
darwin) platform_dir="MacOS" ;;
linux) platform_dir="Linux" ;;
esac
normalize_driver() {
local value
value="$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]')"
case "$value" in
doris|diros) echo "diros" ;;
opengauss|open_gauss|open-gauss) echo "opengauss" ;;
elasticsearch|elastic) echo "elasticsearch" ;;
mariadb|oceanbase|starrocks|sphinx|sqlserver|sqlite|duckdb|dameng|kingbase|highgo|vastbase|iris|mongodb|tdengine|clickhouse)
echo "$value"
;;
*)
return 1
;;
esac
}
public_driver_name() {
case "$1" in
diros) echo "doris" ;;
*) echo "$1" ;;
esac
}
expected_revision_for() {
local target="$1"
awk -v target="$target" '
$0 ~ "\"" target "\"" {
if (match($0, /"src-[^"]+"/)) {
value=substr($0, RSTART + 1, RLENGTH - 2)
print value
exit
}
}
' internal/db/driver_agent_revisions_gen.go
}
build_tags_for_driver() {
local driver="$1"
local tags="gonavi_${driver}_driver"
if [[ "$driver" == "duckdb" && "$host_goos" == "windows" && "$host_goarch" == "amd64" ]]; then
tags="${tags} duckdb_use_lib"
fi
printf '%s\n' "$tags"
}
agent_path_for() {
local driver="$1"
local public_name asset
public_name="$(public_driver_name "$driver")"
asset="${public_name}-driver-agent-${goos}-${goarch}"
if [[ "$goos" == "windows" ]]; then
asset="${asset}.exe"
fi
printf '%s\n' "${assets_dir%/}/${platform_dir}/${asset}"
}
probe_agent_revision() {
local agent_path="$1"
local request
request='{"id":1,"method":"metadata"}'
printf '%s\n' "$request" | "$agent_path" | python3 -c '
import json
import sys
line = sys.stdin.readline()
payload = json.loads(line)
data = payload.get("data") or {}
print(data.get("agentRevision", ""))
'
}
probe_host_agent_revision() {
local driver="$1"
local build_tags probe_dir probe_path revision
build_tags="$(build_tags_for_driver "$driver")"
probe_dir="$(mktemp -d)"
probe_path="${probe_dir}/probe-agent"
if [[ "$host_goos" == "windows" ]]; then
probe_path="${probe_path}.exe"
fi
CGO_ENABLED=0 go build \
-tags "${build_tags}" \
-trimpath \
-ldflags "-s -w" \
-o "${probe_path}" \
./cmd/optional-driver-agent >/dev/null
chmod +x "$probe_path" 2>/dev/null || true
revision="$(probe_agent_revision "$probe_path")"
rm -rf "$probe_dir"
printf '%s\n' "$revision"
}
can_execute_target_binary() {
[[ "$target_platform" == "$host_platform" ]]
}
validate_windows_pe_machine() {
local agent_path="$1"
local expected_goarch="$2"
python3 - "$agent_path" "$expected_goarch" <<'PY'
import os
import struct
import sys
path = sys.argv[1]
goarch = sys.argv[2].strip().lower()
expected = {
"386": 0x014C,
"amd64": 0x8664,
"arm64": 0xAA64,
}
labels = {
0x014C: "windows-386",
0x8664: "windows-amd64",
0xAA64: "windows-arm64",
}
if goarch not in expected:
sys.exit(0)
with open(path, "rb") as fh:
fh.seek(0, os.SEEK_END)
size = fh.tell()
if size < 0x40:
raise SystemExit("文件头不完整")
fh.seek(0)
if fh.read(2) != b"MZ":
raise SystemExit("缺少 MZ 头")
fh.seek(0x3C)
pe_offset_raw = fh.read(4)
if len(pe_offset_raw) != 4:
raise SystemExit("读取 PE 头偏移失败")
pe_offset = struct.unpack("<I", pe_offset_raw)[0]
if pe_offset < 0x40 or pe_offset + 24 > size:
raise SystemExit("PE 头不完整")
fh.seek(pe_offset)
if fh.read(4) != b"PE\0\0":
raise SystemExit("缺少 PE 签名")
machine_raw = fh.read(2)
if len(machine_raw) != 2:
raise SystemExit("读取 PE 架构失败")
machine = struct.unpack("<H", machine_raw)[0]
expected_machine = expected[goarch]
if machine != expected_machine:
raise SystemExit(f"可执行文件架构不兼容(文件={labels.get(machine, hex(machine))},期望={labels[expected_machine]})")
PY
}
declare -a raw_drivers=()
IFS=',' read -r -a raw_drivers <<<"$driver_csv"
host_goos="$(go env GOOS)"
host_goarch="$(go env GOARCH)"
host_platform="${host_goos}/${host_goarch}"
failed=0
for raw_driver in "${raw_drivers[@]}"; do
[[ -n "$raw_driver" ]] || continue
driver="$(normalize_driver "$raw_driver")"
if [[ "$driver" == "duckdb" && "$goos" == "windows" && "$goarch" != "amd64" ]]; then
echo "⚠️ 跳过 duckdb revision 校验($target_platform 不构建 agent"
continue
fi
expected="$(expected_revision_for "$driver")"
if [[ -z "$expected" ]]; then
echo "$driver 缺少期望 revision"
failed=1
continue
fi
agent_path="$(agent_path_for "$driver")"
if [[ ! -f "$agent_path" ]]; then
echo "$driver 缺少 driver-agent 资产:$agent_path"
failed=1
continue
fi
chmod +x "$agent_path" 2>/dev/null || true
if [[ "$goos" == "windows" ]]; then
if ! validate_windows_pe_machine "$agent_path" "$goarch"; then
echo "$driver Windows driver-agent 架构校验失败asset=$agent_path target=$target_platform"
failed=1
continue
fi
fi
actual=""
if can_execute_target_binary; then
actual="$(probe_agent_revision "$agent_path" || true)"
else
echo " runner 平台 ${host_platform} 无法直接执行目标二进制 ${target_platform},已先完成目标资产架构校验,再用 host-native probe 校验相同 build tags 的 revision"
actual="$(probe_host_agent_revision "$driver" || true)"
fi
if [[ "$actual" != "$expected" ]]; then
echo "$driver driver-agent revision 不匹配asset=$agent_path actual=${actual:-} expected=$expected"
failed=1
continue
fi
echo "$driver driver-agent revision 校验通过:$actual"
done
exit "$failed"