mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-30 07:37:36 +00:00
Case (e) of the firewall suite piped `docker exec ... nft list table inet fips` into `grep -q` under pipefail. grep exits at its match; when the exec client was still writing the rest of the listing it took SIGPIPE (141), and pipefail turned a rule that was present into "the sed did not change the scoping rule". It false-failed intermittently in local and GitHub CI. The check moves into table_has in testing/firewall/table-check.sh, which captures the whole listing and then matches it with grep -qF on a here-string, so no pipe is left. It returns 0 when the rule is present, 1 when it is absent and 2 when the table could not be listed; case (e) gives each failure its own message. The assertion is unchanged: same container, same table, same rule text. testing/firewall/table-check-test.sh replaces docker with a shell function that prints the listing in two chunks, the rule in the first and a 0.2 s pause before the second, which is the race's shape. It runs as a guard in every local run (run_fwtable) and as a matching GitHub CI step. With table_has written as the old pipeline, moved verbatim, the test failed (the pipeline's status was 141, the producer's SIGPIPE): FAIL rule present, writer still writing after the match (run 1): returns 0 (rc=1) ... runs 2 to 5 the same PASS rule absent: returns 1 (rc=1) FAIL listing could not be read: returns 2 (rc=1) 6 table_has check(s) failed With the capture form all seven checks pass.
18 lines
745 B
Bash
18 lines
745 B
Bash
#!/bin/bash
|
|
# Sourced by test.sh. Not run on its own.
|
|
|
|
# Return 0 if container $1's `inet fips` table listing contains the fixed text
|
|
# $2, 1 if it does not, and 2 if the listing could not be read.
|
|
#
|
|
# The listing is captured whole before it is matched. Piping `docker exec`
|
|
# straight into `grep -q` under pipefail fails a present rule: grep exits at
|
|
# its match, the exec client still writing the rest takes SIGPIPE (141), and
|
|
# pipefail reports the pipeline as failed. The here-string leaves no pipe, so
|
|
# the result does not depend on how much of the listing follows the match.
|
|
table_has() {
|
|
local listing
|
|
listing=$(docker exec "$1" nft list table inet fips) || return 2
|
|
grep -qF -- "$2" <<<"$listing" && return 0
|
|
return 1
|
|
}
|