fix: quote firewalld rich rules for the remote shell
Some checks failed
deploy / fetch (push) Successful in 17s
deploy / deploy-node (bob.hanzalova.internal, 0x134e73f06fa9bdb1dbfa909e149c563f5860ceb71a0e7307918f7033970edf59, benjy.hanzalova.internal) (push) Failing after 23s
deploy / deploy-miner (1, benjy.hanzalova.internal, bob.hanzalova.internal) (push) Has been skipped
Some checks failed
deploy / fetch (push) Successful in 17s
deploy / deploy-node (bob.hanzalova.internal, 0x134e73f06fa9bdb1dbfa909e149c563f5860ceb71a0e7307918f7033970edf59, benjy.hanzalova.internal) (push) Failing after 23s
deploy / deploy-miner (1, benjy.hanzalova.internal, bob.hanzalova.internal) (push) Has been skipped
run() is `ssh ... "$@"`, and ssh concatenates its argument vector with spaces for the remote shell to re-split, so local quoting is lost. The rich rule arrived as a dozen bare words: firewall-cmd: error: unrecognized arguments: family=ipv4 source address=10.6.0.146/32 service name=quantus-node-miner accept Pass the three rich-rule invocations as one pre-quoted string each. Verified against the real host as gitea_ci: the unquoted form reproduces the CI error, the quoted form returns 'no' — so it parses and the scoped sudoers rule matches it. Every other command in the deploy survived only because no other argument contains a space; CLAUDE.md now records the trap.
This commit is contained in:
@@ -247,11 +247,18 @@ jobs:
|
||||
*) echo "refusing to open ${{ env.MINER_LINK_PORT }}/udp to non-mesh address '${miner_ip}' for ${m}" >&2; exit 1 ;;
|
||||
esac
|
||||
rich="rule family=ipv4 source address=${miner_ip}/32 service name=quantus-node-miner accept"
|
||||
if run sudo firewall-cmd --zone="$zone" --query-rich-rule="$rich"; then
|
||||
# Pass these as ONE pre-quoted string, not as separate run() args.
|
||||
# `run()` is `ssh ... "$@"`, and ssh concatenates its argument vector
|
||||
# with spaces for the REMOTE shell to re-split — so local quoting is
|
||||
# lost and a rich rule arrives as a dozen bare words
|
||||
# ("unrecognized arguments: family=ipv4 source address=..."). Every
|
||||
# other command here survives only because no other argument
|
||||
# contains a space. Keep the inner single quotes.
|
||||
if run "sudo firewall-cmd --zone=$zone --query-rich-rule='$rich'"; then
|
||||
echo "firewalld: rich rule for ${m} already present in ${zone}"
|
||||
else
|
||||
run sudo firewall-cmd --permanent --zone="$zone" --add-rich-rule="$rich"
|
||||
run sudo firewall-cmd --zone="$zone" --add-rich-rule="$rich"
|
||||
run "sudo firewall-cmd --permanent --zone=$zone --add-rich-rule='$rich'"
|
||||
run "sudo firewall-cmd --zone=$zone --add-rich-rule='$rich'"
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
15
CLAUDE.md
15
CLAUDE.md
@@ -52,6 +52,21 @@ without re-measuring:
|
||||
- Node Prometheus is on **9615**, not 9616. Upstream's `MINING.md` parameter
|
||||
table is wrong about this; the running binary is the authority.
|
||||
|
||||
## ssh argument quoting
|
||||
|
||||
`run()` in the deploy is `ssh ... "$@"`. ssh joins its argument vector with
|
||||
spaces and the REMOTE shell re-splits it, so any argument containing a space
|
||||
must be passed as one pre-quoted string:
|
||||
|
||||
```sh
|
||||
run "sudo firewall-cmd --zone=$zone --add-rich-rule='$rich'" # correct
|
||||
run sudo firewall-cmd --zone="$zone" --add-rich-rule="$rich" # word-splits remotely
|
||||
```
|
||||
|
||||
This bit the firewalld rich rules on run 1 and nothing else, because no other
|
||||
argument in the deploy contains a space. Check this before adding any command
|
||||
with a quoted multi-word argument.
|
||||
|
||||
## Working on the deploy
|
||||
|
||||
- The workflow is the source of infra truth (`deployment-gitea-actions.md`).
|
||||
|
||||
Reference in New Issue
Block a user