Files
MoShiro/scripts/smoke-linux.sh
T
justme 29d998bc94
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/verify Pipeline failed
ci/woodpecker/push/dev-image unknown status
build(quic): bundle Linux runtime libraries [CI]
2026-10-10 04:01:24 +08:00

87 lines
5.1 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;需先运行 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
for role in agent probe; do
package_dir="$work/$role-bin"
mkdir -p "$package_dir"
set -- /art/packages/moshiro-"$role"-*-"$rid".tar.gz
[ -f "$1" ] || { echo "missing QUIC-bundled package: $1 (run scripts/package.sh first)" >&2; exit 1; }
tar -xzf "$1" -C "$package_dir"
done
mkdir -p "$work/agent-id"
"$work/agent-bin/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"
"$work/agent-bin/moshiro-agent" --config "$work/agent.json" >"$work/agent.log" 2>&1 &
agent_pid=$!
sleep 3
mkdir -p "$work/probe-id"
"$work/probe-bin/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"
"$work/probe-bin/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"