From 3cfe1b7dd2e5d7c8962c2c966e38a4f24bacd918 Mon Sep 17 00:00:00 2001 From: chen21019 <19357113+chen21019@users.noreply.github.com> Date: Sun, 13 Sep 2026 16:21:35 +0800 Subject: [PATCH] Verify packaged optional CNI binaries in isolated release gate --- .github/workflows/security-release-gate.yml | 1 + README.md | 7 +++ scripts/integration-optional-cni-isolated | 58 +++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100755 scripts/integration-optional-cni-isolated diff --git a/.github/workflows/security-release-gate.yml b/.github/workflows/security-release-gate.yml index 37991ca..a2d402e 100644 --- a/.github/workflows/security-release-gate.yml +++ b/.github/workflows/security-release-gate.yml @@ -139,6 +139,7 @@ jobs: set -euo pipefail cd "$GITHUB_WORKSPACE" IMAGE="$IMAGE" ./scripts/integration-two-node-vxlan + IMAGE="$IMAGE" ./scripts/integration-optional-cni-isolated IMAGE="$IMAGE" \ OLD_IMAGE='ghcr.io/pasturestack/ipsec-vxlan-overlay-network@sha256:4d8a51e04bdd27fea3cb2949158103d43e0d2470907c328f76f7a0c6ccec8608' \ ./scripts/integration-two-node-ipsec diff --git a/README.md b/README.md index 0769e17..523ca8a 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,13 @@ TAG=0.14.33 make package The package build downloads dependencies anonymously, verifies every standalone binary with SHA-256, pins the Ubuntu base image by digest, resolves every directly installed package from Canonical snapshot `20260808T000000Z` with the exact versions in `ubuntu-apt.lock`, and includes the corresponding strongSwan source archives in the image. Go dependencies are declared in `go.mod`, checksum-bound by `go.sum`, and committed in the standard module-aware `vendor` tree for offline builds. +The release gate also runs `scripts/integration-optional-cni-isolated` against +the image it just packaged. Inside a disposable, network-isolated container it +checks the bundled per-host-subnet and flat-bridge CNI binaries through ADD, +bridge connectivity, and DEL. A local reproduction must set `IMAGE` to the +exact image under review. This does not replace a live Catalog, Metadata API, +host-port, cross-host, or host-reboot acceptance test. + The health reconciler canonicalizes strongSwan VICI CHILD_SA runtime names before comparing them with configured peer names. This prevents a VICI unique-ID suffix from being misclassified as a missing SA during a rolling replacement. ## Host firewall backends diff --git a/scripts/integration-optional-cni-isolated b/scripts/integration-optional-cni-isolated new file mode 100755 index 0000000..3bc9491 --- /dev/null +++ b/scripts/integration-optional-cni-isolated @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Exercise the exact CNI binaries bundled in the catalog-pinned image without +# changing the host namespace, managed networks, or Docker daemon settings. +image=${IMAGE:?Set IMAGE to the exact packaged image to verify} +docker image inspect "$image" >/dev/null + +docker run --rm -i --privileged --network none --entrypoint /bin/bash "$image" -s <<'CONTAINER' +set -euo pipefail +export CNI_PATH=/opt/cni/bin CNI_CONTAINERID=optional-cni-smoke CNI_IFNAME=eth0 + +check_link() { + local namespace=$1 address=$2 gateway=$3 + ip netns exec "$namespace" ip -4 address show eth0 | grep -q "$address" + ip netns exec "$namespace" ping -c 2 -W 2 "$gateway" >/dev/null +} + +# Per-host subnet: address allocation and bridge traffic stay inside this +# disposable container's network and mount namespaces. +ip netns add qa-perhost +export CNI_NETNS=/run/netns/qa-perhost 'CNI_ARGS=IgnoreUnknown=1;MACAddress=02:42:37:ff:01:01' +perhost='{"cniVersion":"0.1.0","name":"qa-perhost","type":"pasture-bridge","bridge":"brphqa","bridgeSubnet":"10.55.243.0/24","isDefaultGateway":true,"hostNat":false,"ipam":{"type":"host-local-cni-ipam","subnet":"10.55.243.0/24","dataDir":"/tmp/cni-state"}}' +if ! result=$(CNI_COMMAND=ADD /opt/cni/bin/pasture-bridge <<<"$perhost"); then + printf 'per-host CNI ADD: %s\n' "$result" >&2 + exit 1 +fi +check_link qa-perhost 10.55.243. 10.55.243.1 +CNI_COMMAND=DEL /opt/cni/bin/pasture-bridge <<<"$perhost" >/dev/null +if ip netns exec qa-perhost ip link show eth0 >/dev/null 2>&1; then + echo 'per-host CNI DEL left eth0 behind' >&2 + exit 1 +fi +ip netns del qa-perhost +echo 'PER_HOST_CNI=pass' + +# Flat bridge: the physical LAN bridge is represented by a pre-created +# bridge inside this container. A direct address avoids depending on a real +# platform Metadata API; the Metadata lookup path has its own source tests. +ip link add brflatqa type bridge +ip address add 10.55.244.1/24 dev brflatqa +ip link set brflatqa up +ip netns add qa-flat +export CNI_NETNS=/run/netns/qa-flat 'CNI_ARGS=IgnoreUnknown=1;MACAddress=02:42:37:ff:01:02;IPAddress=10.55.244.2/24' +flat='{"cniVersion":"0.1.0","name":"qa-flat","type":"pasture-bridge","bridge":"brflatqa","bridgeSubnet":"10.55.244.1/24","skipBridgeConfigureIP":true,"skipFastPath":true,"hostNat":false,"ipam":{"type":"flat-cni-ipam","metadataAddress":"169.254.169.250"}}' +if ! result=$(CNI_COMMAND=ADD /opt/cni/bin/pasture-bridge <<<"$flat"); then + printf 'flat CNI ADD: %s\n' "$result" >&2 + exit 1 +fi +check_link qa-flat 10.55.244.2 10.55.244.1 +CNI_COMMAND=DEL /opt/cni/bin/pasture-bridge <<<"$flat" >/dev/null +if ip netns exec qa-flat ip link show eth0 >/dev/null 2>&1; then + echo 'flat CNI DEL left eth0 behind' >&2 + exit 1 +fi +ip netns del qa-flat +echo 'FLAT_CNI=pass' +CONTAINER