80 lines
4.8 KiB
Bash
80 lines
4.8 KiB
Bash
#!/bin/sh
|
||
# 在 Linux 容器里用发布出来的 NativeAOT 二进制跑一遍完整链路:后端 → 注册 Agent → Agent → Probe → 数据落库。
|
||
#
|
||
# RID=linux-musl-x64 IMAGE=alpine:3.22 (默认)
|
||
# RID=linux-x64 IMAGE=debian:bookworm-slim
|
||
# MODE=install 用打包产物里的 install.sh 安装(agent 注册、probe 身份、以 moshiro 用户运行),而不是直接运行二进制
|
||
#
|
||
# 用法(在仓库根目录;Windows 下先 export MSYS_NO_PATHCONV=1;MODE=install 需要先运行 scripts/package.sh):
|
||
# docker run --rm -e RID -e MODE -v "$PWD/backend/artifacts:/art:ro" -v "$PWD/scripts/smoke-linux.sh:/smoke.sh:ro" $IMAGE sh /smoke.sh [秒数]
|
||
set -eu
|
||
seconds="${1:-60}"
|
||
rid="${RID:-linux-musl-x64}"
|
||
mode="${MODE:-direct}"
|
||
pub=/art/publish
|
||
|
||
if command -v apk >/dev/null 2>&1; then
|
||
apk add --no-cache curl jq libssl3 libstdc++ >/dev/null
|
||
else
|
||
apt-get update >/dev/null && apt-get install -y --no-install-recommends curl jq ca-certificates libssl3 >/dev/null
|
||
fi
|
||
|
||
work=/tmp/smoke
|
||
mkdir -p "$work/data" "$work/probe"
|
||
base=http://127.0.0.1:18080
|
||
|
||
export ASPNETCORE_URLS="$base" MoShiro__DataDirectory="$work/data" MoShiro__InitialAdminUser=admin \
|
||
MoShiro__InitialAdminPassword="correct horse battery" MoShiro__SecureCookies=false
|
||
(cd "$pub/backend/$rid" && ./moshiro-backend >"$work/backend.log" 2>&1 &)
|
||
for i in $(seq 1 60); do curl -fs "$base/healthz" >/dev/null 2>&1 && break; sleep 1; done
|
||
curl -fs "$base/healthz" >/dev/null || { cat "$work/backend.log"; echo "backend did not start"; exit 1; }
|
||
echo "backend up"
|
||
|
||
login=$(curl -si -X POST "$base/api/admin/auth/login" -H 'Content-Type: application/json' -d '{"username":"admin","password":"correct horse battery"}')
|
||
cookie=$(echo "$login" | grep -i '^set-cookie' | head -1 | sed 's/^[^:]*: //; s/;.*//' | tr -d '\r')
|
||
csrf=$(echo "$login" | tail -1 | jq -r .csrf_token)
|
||
token=$(curl -fs -X POST "$base/api/admin/api-tokens" -H "Cookie: $cookie" -H "X-CSRF-Token: $csrf" -H 'Content-Type: application/json' -d '{"name":"smoke","scope":"admin"}' | jq -r .plaintext)
|
||
auth="Authorization: Bearer $token"
|
||
join=$(curl -fs -X POST "$base/api/admin/join-tokens" -H "$auth" -H 'Content-Type: application/json' -d '{"auto_approve":true,"max_uses":1,"expires_in_hours":1}' | jq -r .plaintext)
|
||
probe_join=$(curl -fs -X POST "$base/api/admin/join-tokens" -H "$auth" -H 'Content-Type: application/json' -d '{"role":"probe","max_uses":1,"expires_in_hours":1}' | jq -r .plaintext)
|
||
|
||
if [ "$mode" = install ]; then
|
||
# 安装到 /usr/lib/moshiro 和 /etc/moshiro,以 moshiro 用户运行(没有 systemd:自己启动)
|
||
mkdir -p /tmp/pkg && for role in agent probe; do tar -C /tmp/pkg -xzf /art/packages/moshiro-$role-*-$rid.tar.gz; done
|
||
(cd /tmp/pkg/moshiro-agent-* && ./install.sh agent --server "$base" --join "$join" --name smoke-agent --no-start)
|
||
ls -l /usr/lib/moshiro /etc/moshiro
|
||
run_as() { su -s /bin/sh moshiro -c "exec $*"; }
|
||
run_as /usr/lib/moshiro/moshiro-agent --config /etc/moshiro/agent.json >"$work/agent.log" 2>&1 &
|
||
agent_pid=$!
|
||
sleep 3
|
||
(cd /tmp/pkg/moshiro-probe-* && ./install.sh probe --server "$base" --join "$probe_join" --name smoke-probe --no-start)
|
||
run_as /usr/lib/moshiro/moshiro-probe --config /etc/moshiro/probe.json >"$work/probe.log" 2>&1 &
|
||
probe_pid=$!
|
||
else
|
||
mkdir -p "$work/agent-id"
|
||
"$pub/fleet-enroll/$rid/fleet-enroll" --server "$base" --join "$join" --name smoke-agent --identity-dir "$work/agent-id"
|
||
printf '{"fleet":{"server":"%s","identity_dir":"%s"},"listen":{"bind":"127.0.0.1"}}' "$base" "$work/agent-id" >"$work/agent.json"
|
||
"$pub/agent/$rid/moshiro-agent" --config "$work/agent.json" >"$work/agent.log" 2>&1 &
|
||
agent_pid=$!
|
||
sleep 3
|
||
mkdir -p "$work/probe-id"
|
||
"$pub/fleet-enroll/$rid/fleet-enroll" --server "$base" --join "$probe_join" --name smoke-probe --identity-dir "$work/probe-id"
|
||
printf '{"fleet":{"server":"%s","identity_dir":"%s"}}' "$base" "$work/probe-id" >"$work/probe/probe.json"
|
||
"$pub/probe/$rid/moshiro-probe" --config "$work/probe/probe.json" >"$work/probe.log" 2>&1 &
|
||
probe_pid=$!
|
||
fi
|
||
|
||
rss() { awk '/VmRSS/ {printf "%.1f", $2/1024}' "/proc/$1/status"; }
|
||
i=0
|
||
while [ "$i" -lt "$seconds" ]; do
|
||
sleep 10; i=$((i + 10))
|
||
echo "t+${i}s probe=$(rss "$probe_pid")MB agent=$(rss "$agent_pid")MB"
|
||
done
|
||
|
||
echo "agents: $(curl -fs "$base/api/admin/agents" -H "$auth" | jq -c '[.items[] | {name, status, probe_connected}]')"
|
||
echo "chunks: $(curl -fs "$base/api/admin/raw/chunks" -H "$auth" | jq -c '[.items[].kind] | group_by(.) | map({(.[0]): length}) | add')"
|
||
agent_id=$(curl -fs "$base/api/admin/agents" -H "$auth" | jq -r '.items[0].id')
|
||
echo "tcp summary: $(curl -fs "$base/api/public/lines/$agent_id/series?range=5m&step=1s&metrics=tcp.rtt.p50,tcp.rtt.p999,tcp.rtt.max,tcp.rtt.tail,tcp.slow,tcp.retrans,tcp.srtt.p95" -H "$auth" | jq -c '.summary.metrics')"
|
||
echo "--- probe.log"; tail -4 "$work/probe.log"
|
||
echo "--- agent.log"; tail -4 "$work/agent.log"
|