Skip to content

Commit b8c1139

Browse files
committed
replace client telemetry and traffic with native agent
1 parent 7eba0af commit b8c1139

69 files changed

Lines changed: 4718 additions & 3369 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.dockerignore‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.git
2+
.github
3+
.netopsbench*
4+
.mypy_cache
5+
.pytest_cache
6+
.ruff_cache
7+
.venv
8+
build
9+
dist
10+
*.egg-info
11+
**/__pycache__
12+
**/*.py[cod]
13+
14+
docs
15+
examples
16+
lab-topology
17+
scenario_results
18+
scenarios
19+
scripts
20+
tests
21+
native/client-agent/target

‎.env.example‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ NETOPSBENCH_INFLUXDB_BUCKET=netopsbench
3232
# NETOPSBENCH_LOG_LEVEL=INFO # DEBUG | INFO | WARNING | ERROR
3333
# NETOPSBENCH_NO_SUDO=0 # Set to 1 in CI/test environments without sudo
3434
# NETOPSBENCH_PYTHON=/path/to/python3 # Interpreter used by repository shell wrappers
35-
# NETOPSBENCH_TRAFFIC_PARALLELISM=32 # Parallel docker exec workers for benchmark traffic start/stop
3635

3736
# --- Optional semantic fault-type judge ---
3837
# NETOPSBENCH_FAULT_TYPE_JUDGE_ENABLED=0
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: client-agent-image
2+
3+
on:
4+
push:
5+
branches:
6+
- "codex/**"
7+
tags:
8+
- "v*"
9+
paths:
10+
- ".github/workflows/client-agent-image.yml"
11+
- "containers/client/**"
12+
- "native/client-agent/**"
13+
workflow_dispatch:
14+
15+
permissions:
16+
contents: read
17+
packages: write
18+
19+
jobs:
20+
publish:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v4
24+
25+
- uses: docker/login-action@v3
26+
with:
27+
registry: ghcr.io
28+
username: ${{ github.actor }}
29+
password: ${{ secrets.GITHUB_TOKEN }}
30+
31+
- uses: docker/setup-buildx-action@v3
32+
33+
- name: Set immutable image tags
34+
id: tags
35+
shell: bash
36+
run: |
37+
tags="ghcr.io/netx-lab/netopsbench-client:sha-${GITHUB_SHA}"
38+
if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
39+
tags="${tags}"$'\n'"ghcr.io/netx-lab/netopsbench-client:${GITHUB_REF_NAME}"
40+
fi
41+
{
42+
echo "value<<EOF"
43+
echo "${tags}"
44+
echo "EOF"
45+
} >> "${GITHUB_OUTPUT}"
46+
47+
- name: Build and publish linux/amd64 image
48+
id: build
49+
uses: docker/build-push-action@v6
50+
with:
51+
context: .
52+
file: containers/client/Dockerfile
53+
platforms: linux/amd64
54+
push: true
55+
provenance: false
56+
tags: ${{ steps.tags.outputs.value }}
57+
58+
- name: Publish manifest digest
59+
run: echo "digest=${{ steps.build.outputs.digest }}" >> "${GITHUB_STEP_SUMMARY}"

‎.github/workflows/test.yml‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,44 @@ on:
99
pull_request:
1010

1111
jobs:
12+
rust:
13+
runs-on: ubuntu-latest
14+
defaults:
15+
run:
16+
working-directory: native/client-agent
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
21+
- name: Install pinned Rust
22+
run: |
23+
rustup toolchain install 1.97.1 --profile minimal --component clippy,rustfmt
24+
rustup default 1.97.1
25+
26+
- name: Format
27+
run: cargo fmt --check
28+
29+
- name: Clippy
30+
run: cargo clippy --locked --all-targets -- -D warnings
31+
32+
- name: Test
33+
run: cargo test --locked
34+
35+
client-image:
36+
runs-on: ubuntu-latest
37+
steps:
38+
- name: Checkout
39+
uses: actions/checkout@v4
40+
41+
- name: Build client image
42+
run: docker build -f containers/client/Dockerfile -t netopsbench-client:test .
43+
44+
- name: Verify native-only runtime
45+
run: |
46+
docker run --rm netopsbench-client:test netopsbench-client-agent --version
47+
docker run --rm netopsbench-client:test sh -lc \
48+
'command -v ping && command -v traceroute && ! command -v python3 && ! command -v iperf3'
49+
1250
lint:
1351
runs-on: ubuntu-latest
1452
steps:

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
__pycache__/
2+
native/client-agent/target/
23
*.py[cod]
34
*$py.class
45
.venv/

‎containers/client/Dockerfile‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# syntax=docker/dockerfile:1
2+
FROM rust:1.97.1-alpine3.24@sha256:3c38f3f82c2f3d73da3b38e18d279393a04cb43ddded0e35088a8c3324d40900 AS builder
3+
4+
RUN apk add --no-cache musl-dev
5+
WORKDIR /src/native/client-agent
6+
COPY native/client-agent/Cargo.toml native/client-agent/Cargo.lock native/client-agent/rust-toolchain.toml ./
7+
COPY native/client-agent/src ./src
8+
RUN cargo build --locked --release --target x86_64-unknown-linux-musl
9+
10+
FROM alpine:3.24.1@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b
11+
12+
RUN apk add --no-cache \
13+
bash \
14+
ca-certificates \
15+
curl \
16+
ethtool \
17+
iproute2 \
18+
iputils \
19+
procps \
20+
tcpdump \
21+
traceroute
22+
23+
COPY --from=builder \
24+
/src/native/client-agent/target/x86_64-unknown-linux-musl/release/netopsbench-client-agent \
25+
/usr/local/bin/netopsbench-client-agent
26+
27+
CMD ["sleep", "infinity"]

‎docs/content/docs/debug-operate/observability.mdx‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,11 @@ bash scripts/runtime/deploy.sh xs lab-topology
9191
export NETOPSBENCH_TOPOLOGY_DIR="$PWD/lab-topology/generated_topology_xs"
9292
```
9393

94-
`deploy.sh` generates topology metadata, renders Telegraf config, starts InfluxDB / Telegraf / Grafana, and deploys Pingmesh agents.
94+
`deploy.sh` generates topology metadata, renders Telegraf config, starts InfluxDB / Telegraf / Grafana, and starts the native Pingmesh and background-traffic processes in each client.
95+
96+
The default client image is pinned by digest. A custom client image must provide
97+
`/usr/local/bin/netopsbench-client-agent`; runtime preparation fails explicitly
98+
when the binary is absent.
9599

96100
Common overrides:
97101

‎docs/content/docs/run-benchmarks/interactive-simulator.mdx‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ tool and diagnosis actions. Install `netopsbench[simulator]` and run
5757
from accepting additional tool or submit actions after its deadline; it does
5858
not attempt to terminate arbitrary user threads while an action is running.
5959

60-
When using a large topology, keep only that topology's Pingmesh, BGP collector,
61-
and Telegraf processes active on the host. Other labs may remain deployed and
62-
warm. See the observation-validity guidance in
60+
Large warm topologies may keep their native Pingmesh, BGP collector, and
61+
Telegraf processes active together. The simulator still rejects an incident
62+
when the active topology does not meet readiness or complete-coverage gates.
63+
See the observation-validity guidance in
6364
[Benchmark Methodology](/docs/run-benchmarks/methodology).

‎docs/content/docs/run-benchmarks/methodology.mdx‎

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,28 @@ Scenarios are generated from the packaged canonical campaign spec. Running `neto
5959

6060
## Observation validity
6161

62-
Pingmesh compares an explicit healthy baseline with the fault observation window. A path is reported as a latency spike only when the median `rtt_avg` for that source/destination path increases by at least 20 ms; an isolated RTT peak does not qualify. This rule is shared by built-in and custom topologies and intentionally does not detect smaller latency changes.
62+
Pingmesh compares an explicit healthy baseline with the fault observation
63+
window. A path is reported as a latency spike when its median `rtt_avg`
64+
increases by at least 20 ms, or when the median increases by at least 20 ms in
65+
two independent ECMP port batches. A peak or a single elevated port batch does
66+
not qualify. Packet-loss evidence likewise combines a strong per-path count
67+
with source/destination leaf concentration, so uniformly distributed
68+
background loss is not presented as a localized fault. These rules are shared
69+
by built-in and custom topologies.
6370

6471
Background traffic must start its complete topology-derived flow matrix before the baseline is captured. A partial matrix is an infrastructure-invalid case, rather than a degraded observation presented to the agent.
6572

66-
On one host, run observability for only one large topology at a time. Other
67-
Containerlab topologies may remain deployed and warm, but pause their Pingmesh,
68-
BGP collector, and Telegraf processes while measuring the active large
69-
topology. Co-running multiple large telemetry pipelines causes host scheduling
70-
pressure that can appear as network latency. This is an operational constraint,
71-
not part of scenario or detector semantics.
72-
73-
The 0.2 collector retains complete BGP snapshots. On xlarge topologies this
74-
file-to-Telegraf path may fall behind its 10-second polling interval, so use
75-
the tool's reported data freshness when interpreting BGP event evidence.
73+
Each topology sends native Pingmesh batches through its topology-local
74+
Telegraf listener. Multiple warm topologies may therefore keep observability
75+
active together; readiness and complete coverage remain mandatory for every
76+
case. Host capacity is not hidden by a longer timeout or a topology-specific
77+
detector threshold.
78+
79+
The 0.2 collector polls BGP every 10 seconds. On topologies with more than 128
80+
routing devices, every poll writes the collection index, state transitions,
81+
and all non-Established neighbors; stable complete-neighbor snapshots are
82+
written every 60 seconds. Use the tool's reported data freshness when
83+
interpreting BGP evidence.
7684

7785
## Scoring dimensions
7886

‎docs/content/docs/run-benchmarks/run-scenario-vs-suite.mdx‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ Useful environment overrides:
103103
| `BENCH_SCALES` | Space-separated scale list such as `xs small`. |
104104
| `BENCH_WORKERS_<SCALE>` | Worker count override for one scale, for example `BENCH_WORKERS_LARGE=2`. |
105105
| `BENCH_CLEAN_RUNS=1` | Explicitly remove previous `.netopsbench/runs/` artifacts before the batch. By default, previous reports and traces are preserved. |
106-
| `NETOPSBENCH_TRAFFIC_PARALLELISM` | Bounded client traffic start/stop concurrency; defaults to 32. |
107106

108107
The script writes logs under `scenario_results/benchmark_logs_<timestamp>/`, records the run ids for the batch in `benchmark_runs_<timestamp>.jsonl`, and writes a CSV summary under `scenario_results/benchmark_summary_<timestamp>.csv`. Run artifacts use timestamp ids such as `run-20260605T124040Z`; use `netopsbench trace view` to sync trace-enabled runs into the local Harbor viewer cache and inspect saved traces.
109108

0 commit comments

Comments
 (0)