Ver Fonte

Add OpenWrt 23.05.6 testbed (Dockerfile, fetcher, runner docs)

- Dockerfile-2305: scratch image from the official 23.05.6 x86_64
  rootfs tarball + lua/liblua5.1.5/openssl-util/libopenssl3/ca-bundle
  ipk payloads (busybox tar can't read .ipk ar archives, so the
  payloads are pre-extracted on the host and COPYed)
- download-2305.sh: idempotent fetcher (rootfs + 5 .ipks + pre-extract)
- testbed/README.md: build/run steps for 19.07 + 23.05, docker-cp
  destination-missing gotcha, ipk/liblua gotchas
- .gitignore: keep the multi-MB fetched artifacts out of git
- dlog: 23.05 result — base lua package is Lua 5.1.5 (the '23.05
  ships 5.4' hypothesis is false; no compat pass needed), all 7
  suites pass, daemon dry-run clean. 19.07 container removed.
Gogs há 1 mês atrás
pai
commit
ca06cf490d
5 ficheiros alterados com 260 adições e 0 exclusões
  1. 73 0
      balancer-lite-lua.dlog
  2. 5 0
      testbed/.gitignore
  3. 45 0
      testbed/Dockerfile-2305
  4. 77 0
      testbed/README.md
  5. 60 0
      testbed/download-2305.sh

+ 73 - 0
balancer-lite-lua.dlog

@@ -246,3 +246,76 @@ lua5.1 src/balancerlite/main.lua \
 - Real (non-dry-run) end-to-end actuator test (needs `ip`/`wg` on a
   real interface).
 - Optional: procd SIGHUP hot-reload; signed-webhook outbox unit tests.
+
+## 2026-09-05 OpenWrt 23.05 testbed built + full suite green
+
+### What
+Built a second testbed on **OpenWrt 23.05.6 x86_64** (the user's follow-up
+request after the 19.07 pass). The 19.07 container was shut down
+(`stop.sh --rm`) first.
+
+Key finding: the "23.05 ships Lua 5.4" hypothesis is **false** —
+OpenWrt 23.05's base `lua` package is **Lua 5.1.5** (same major as
+19.07), so **no 5.4-compat pass is needed**. The existing 5.1-targeted
+code runs unmodified.
+
+### How the 23.05 image is built
+There is **no** `shellspec/openwrt` tag for 23.05 (that repo tops out
+at 19.07.7), and Docker Hub's `openwrt/rootfs` only has 24.10/25.12
+for x86_64. So `testbed/Dockerfile-2305` builds from the **official
+23.05.6 x86_64 rootfs tarball** (downloads.openwrt.org) + four .ipk
+payloads from the 23.05.6 feeds:
+
+- `lua` + `liblua5.1.5` — Lua 5.1.5 interpreter + its shared lib
+- `openssl-util` + `libopenssl3` + `ca-bundle` — `sha256.lua` uses `openssl dgst`
+
+Two build gotchas (both hit): busybox `tar` can't read `.ipk` (ar)
+archives, so .ipk payloads are extracted on the **host** (GNU tar) and
+`COPY`ed; and `lua` alone is not enough — it's a symlink to `lua5.1`
+which needs the separate `liblua5.1.5` .ipk (else `lua -v` dies on
+"Error loading shared library liblua.so.5.1.5").
+
+New files:
+- `testbed/Dockerfile-2305` — scratch build from official rootfs + ipk payloads
+- `testbed/download-2305.sh` — idempotent fetcher for rootfs + 5 .ipks + pre-extract
+- `testbed/README.md` — how to build/run both 19.07 & 23.05 testbeds + docker-cp gotcha
+- `testbed/.gitignore` — ignores the large fetched artifacts (rootfs/, ipks/, ipk-extract/)
+
+### Test Results (OpenWrt 23.05.6 testbed, Lua 5.1.5)
+```
+ALL 7 SUITES PASS
+  sha256      → 3/3 vectors PASS (openssl dgst present)
+  state       → PASS
+  routing     → 32/32
+  wg          → 35/35
+  ctl         → 42/42
+  smoke       → 21/21  (incl. [1b] wan-section-load checks)
+  probes_config → 21/21
+daemon --dry-run → "(DRY RUN)" banner, routing cmds printed,
+                   "exited after 1 cycles", rc=0, no crash, no
+                   "unsafe iface/gw" warnings
+```
+
+### Verify commands
+```sh
+cd /root/.openclaw/workspace/balancer-lite-lua/testbed
+./download-2305.sh
+docker build -f Dockerfile-2305 -t openwrt-testbed-2305:latest .
+S=skills/openwrt-testbed/scripts
+OPENWRT_TESTBED_NAME=openwrt-testbed-2305 OPENWRT_TESTBED_IMAGE=openwrt-testbed-2305:latest $S/start.sh
+# then run testbed-runner.lua inside (see testbed/README.md)
+```
+
+### Notes
+- 23.05 testbed container `openwrt-testbed-2305` left **running** (image
+  cached, ready to reuse). Image is ~small (scratch + 2.7MB rootfs +
+  ipk payloads).
+- 19.07 container was `stop.sh --rm`'d (gone). 23.05 is the active testbed.
+- Hypothesis log: 23.05 → Lua **5.1.5** (not 5.4). If a future OpenWrt
+  bumps base lua to 5.4, revisit: `goto`, `#` on nil, integer-division
+  (`//` vs `/`) semantics. Not needed now.
+
+### Open loops
+- Real (non-dry-run) end-to-end actuator test (needs `ip`/`wg` on a live
+  interface — neither testbed has `wg` installed).
+- Optional: procd SIGHUP hot-reload; signed-webhook outbox unit tests.

+ 5 - 0
testbed/.gitignore

@@ -0,0 +1,5 @@
+# Large/fetched artifacts — regenerated by download-2305.sh
+openwrt-23.05.6-x86-64-rootfs.tar.gz
+rootfs/
+ipk-extract/
+ipks/

+ 45 - 0
testbed/Dockerfile-2305

@@ -0,0 +1,45 @@
+# syntax=docker/dockerfile:1
+# OpenWrt 23.05.6 x86_64 testbed image.
+#
+# Built from the official OpenWrt 23.05.6 rootfs tarball (downloads.openwrt.org)
+# + a small set of .ipk packages from the 23.05.6 feeds:
+#   - lua + liblua5.1.5 (Lua 5.1.5 — OpenWrt's base lua package is
+#     still 5.1, NOT 5.4)
+#   - openssl-util + libopenssl3 + ca-bundle (sha256.lua uses `openssl dgst`)
+#
+# .ipk files are ar archives (busybox tar can't read them), so they are
+# pre-extracted on the host into ipk-extract/ (see download-2305.sh) and
+# simply COPYed into the image.
+#
+# Build (from balancer-lite-lua/testbed):
+#   docker build -f Dockerfile-2305 -t openwrt-testbed-2305:latest .
+#
+# Run with the standard openwrt-testbed skill scripts via env override:
+#   OPENWRT_TESTBED_NAME=openwrt-testbed-2305 \
+#   OPENWRT_TESTBED_IMAGE=openwrt-testbed-2305:latest \
+#   skills/openwrt-testbed/scripts/start.sh
+#
+# Note: this image is NOT the skill's default image. The skill's 19.07
+# Dockerfile (shellspec/openwrt + luasocket) is left untouched.
+
+FROM scratch
+
+# Official 23.05.6 x86_64 rootfs (pre-extracted on the host; see
+# download-2305.sh). Extracted as ./ into the image root.
+COPY rootfs/ /
+
+# Pre-extracted package payloads (lua, liblua5.1.5, openssl-util,
+# libopenssl3, ca-bundle) from the 23.05.6 feeds.
+COPY ipk-extract/ /
+
+# Lua paths + workspace for test fixtures. OpenWrt's Lua binary
+# doesn't include versioned paths in its compiled-in package.path,
+# so export them via profile.d (the test driver also sets them
+# inline in every docker exec).
+RUN mkdir -p /var/lock /var/run /tmp /etc/profile.d /testbed \
+    && rm -rf /var/opkg-lists/* \
+    && echo 'export LUA_PATH="/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua;;"' > /etc/profile.d/lua-paths.sh \
+    && echo 'export LUA_CPATH="/usr/lib/lua/5.1/?.so;/usr/lib/lua/?.so;;"' >> /etc/profile.d/lua-paths.sh
+
+# NB: busybox's `sleep` doesn't understand "infinity" — use 1 year.
+CMD ["sleep", "31536000"]

+ 77 - 0
testbed/README.md

@@ -0,0 +1,77 @@
+# testbed/ — OpenWrt testbeds for balancer-lite-lua
+
+Two OpenWrt container testbeds, driven by the standard
+`openwrt-testbed` skill scripts (`skills/openwrt-testbed/scripts/`).
+
+## 19.07 (skill default — image built by the skill)
+
+```sh
+S=skills/openwrt-testbed/scripts
+$S/start.sh                          # builds openwrt-testbed:latest from shellspec/openwrt
+$S/stop.sh --rm                      # shut down + remove
+```
+
+Image: `openwrt-testbed:latest` (shellspec/openwrt 19.07.7 + luasocket).
+Note: it ships **no openssl** — run `opkg update && opkg install
+openssl-util` inside the container before `tests/sha256.lua` can pass.
+
+## 23.05 (this directory)
+
+```sh
+cd testbed
+./download-2305.sh                   # fetches rootfs + .ipks (idempotent)
+docker build -f Dockerfile-2305 -t openwrt-testbed-2305:latest .
+OPENWRT_TESTBED_NAME=openwrt-testbed-2305 \
+OPENWRT_TESTBED_IMAGE=openwrt-testbed-2305:latest \
+$S/start.sh
+```
+
+Image: `openwrt-testbed-2305:latest`, built from the **official
+OpenWrt 23.05.6 x86_64 rootfs tarball** (downloads.openwrt.org) plus
+four .ipk payloads from the 23.05.6 feeds:
+
+| package | why |
+|---|---|
+| `lua` + `liblua5.1.5` | Lua **5.1.5** interpreter (OpenWrt 23.05's base `lua` package is still 5.1 — the "23.05 ships Lua 5.4" hypothesis is **false**; no 5.4-compat pass needed) |
+| `openssl-util` + `libopenssl3` + `ca-bundle` | `sha256.lua` shells out to `openssl dgst` |
+
+Why a scratch build: the official Docker Hub `openwrt/rootfs` repo has
+no 23.05 x86_64 tag (only 24.10/25.12), and `shellspec/openwrt` tops
+out at 19.07.7. Building from the official rootfs tarball keeps the
+testbed a real OpenWrt rootfs with real busybox/opkg/uci.
+
+Build gotchas (both hit in 2026-09):
+- busybox `tar` **cannot read `.ipk`** (ar archives) → extract on the
+  host (host GNU tar handles them) and `COPY` the payload tree.
+- the `lua` .ipk alone is not enough: `lua` is a symlink to `lua5.1`
+  which needs `liblua5.1.5` (separate .ipk) — without it `lua -v`
+  dies with "Error loading shared library liblua.so.5.1.5".
+
+## Running the balancerlite suite inside either testbed
+
+```sh
+R=/root/.openclaw/workspace/balancer-lite-lua
+C=openwrt-testbed          # or openwrt-testbed-2305
+
+docker exec $C sh -c 'rm -rf /testbed/src /testbed/tests; mkdir -p /testbed/src'
+docker cp $R/src/balancerlite $C:/testbed/src/balancerlite
+docker cp $R/tests          $C:/testbed/tests
+docker cp $R/testbed/testbed-runner.lua $C:/testbed/testbed-runner.lua
+docker exec $C sh -c 'cd /testbed && lua testbed-runner.lua'
+```
+
+Daemon dry-run:
+
+```sh
+docker exec $C sh -c 'mkdir -p /tmp/bl_state'
+sed "s|/root/balancerlite|/tmp/bl_state|" $R/etc/config/balancerlite.example > /tmp/cfg
+docker cp /tmp/cfg $C:/testbed/etc-cfg
+docker exec $C sh -c 'cd /testbed && lua src/balancerlite/main.lua --config /testbed/etc-cfg --dry-run'
+# expect: "(DRY RUN)" banner + "exited after 1 cycles", rc=0
+```
+
+⚠️ `docker cp` gotcha: if the destination path **doesn't exist**, the
+source *directory itself* is copied under the destination name
+(nesting bug — the runner then silently tests a stale copy). Always
+`mkdir -p` the destination (or `rm -rf` + `mkdir -p` in one
+`sh -c`), and `md5sum` a file after the copy to verify.

+ 60 - 0
testbed/download-2305.sh

@@ -0,0 +1,60 @@
+#!/bin/sh
+# download-2305.sh — fetch the OpenWrt 23.05.6 x86_64 rootfs and the
+# few .ipk packages the testbed needs, and pre-extract them.
+#
+# Idempotent: skips any artifact that already exists.
+#
+# Run from balancer-lite-lua/testbed/.
+
+set -e
+cd "$(dirname "$0")"
+
+VER=23.05.6
+BASE_URL="https://downloads.openwrt.org/releases/$VER"
+ROOTFS="$VER-x86-64-rootfs.tar.gz"
+
+mkdir -p ipks
+
+# 1. Official rootfs tarball
+if [ ! -f "$ROOTFS" ]; then
+    echo "Fetching $ROOTFS ..."
+    curl -fSL -o "$ROOTFS" "$BASE_URL/targets/x86/64/openwrt-$ROOTFS"
+fi
+
+# 2. .ipk payloads (from the 23.05.6 x86_64 base feed)
+fetch_ipk() {
+    f="$1"
+    if [ -f "ipks/$f" ]; then
+        echo "  $f: present"
+        return 0
+    fi
+    for feed in "packages/x86_64/base" "packages/x86_64/packages" "packages/x86_64/routing" "targets/x86/64/packages"; do
+        if curl -fsSL -o "ipks/$f" "$BASE_URL/$feed/$f"; then
+            echo "  $f: fetched from $feed"
+            return 0
+        fi
+    done
+    echo "  $f: NOT FOUND in any feed" >&2
+    rm -f "ipks/$f"
+    return 1
+}
+
+fetch_ipk lua_5.1.5-11_x86_64.ipk
+fetch_ipk liblua5.1.5_5.1.5-11_x86_64.ipk
+fetch_ipk openssl-util_3.0.9-2_x86_64.ipk
+fetch_ipk libopenssl3_3.0.9-2_x86_64.ipk
+fetch_ipk ca-bundle_20241223-1_all.ipk
+
+# 3. Pre-extract rootfs (busybox tar in the image can't read the
+#    ar-based .ipk either, so extraction happens on the host)
+if [ ! -d rootfs ] || [ -z "$(ls -A rootfs 2>/dev/null)" ]; then
+    rm -rf rootfs ipk-extract
+    mkdir -p rootfs ipk-extract
+    echo "Extracting rootfs + ipk payloads ..."
+    tar xzf "$ROOTFS" -C rootfs
+    for ipk in ipks/*.ipk; do
+        tar -xOf "$ipk" ./data.tar.gz | tar -xz -C ipk-extract
+    done
+fi
+
+echo "Done. Build with: docker build -f Dockerfile-2305 -t openwrt-testbed-2305:latest ."