#!/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"