Repository navigation
NAS-144733 / 28.0.0-BETA.1 / truenas-appliance-runner: wait for node B to answer ssh from a new boot after giving it its own ids - #24
Conversation
…ot after giving it its own ids
| sleep 5 | ||
| done | ||
| if [ -z "$now" ] || [ "$now" = "$boot" ]; then | ||
| die "node B did not come back over ssh from its reboot within 10 minutes" |
There was a problem hiding this comment.
LOW — "within 10 minutes" counts only the sleep 5. Each attempt also runs ssh_, and ssh_ sets ConnectTimeout=10. While B is down, an attempt costs anywhere from about 3 s (no ARP reply, so EHOSTUNREACH) to the full 10 s. So 120 attempts take roughly 16 to 30 minutes, not 10. The loop does still terminate, so it can't hang. But the message understates how long the job waited, and it is easy to misread next to a step timeout. You could bound the loop by wall-clock time instead, e.g. deadline=$((SECONDS + 600)) and while [ "$SECONDS" -lt "$deadline" ]. Or the message could just say "after 120 tries".
|
One finding: one LOW. No human review needed. The change replaces the old "ssh stopped answering" wait with a check on
Callers see no change in inputs, outputs or documented behaviour, so |
…ing refused connections
| # not up) is just tried again. | ||
| deadline=$((SECONDS + 600)) | ||
| while [ "$SECONDS" -lt "$deadline" ]; do | ||
| now="$(ssh_ b cat /proc/sys/kernel/random/boot_id 2>/dev/null)" || now= |
There was a problem hiding this comment.
LOW — The 10-minute deadline is only checked between polls, so it doesn't cap a single poll. ConnectTimeout=10 only covers connection setup. ssh_ sets no ServerAliveInterval/ServerAliveCountMax, so if a poll connects just before B's guest resets (the old boot's sshd is still up during shutdown), the reset sends no RST. That ssh call can then block on a dead TCP connection far past the deadline, and the die never fires. The window is small because cat returns at once, so this is unlikely. If you want "by the clock" to actually hold, add -o ServerAliveInterval=5 -o ServerAliveCountMax=2 here (or in ssh_), or wrap the poll in timeout 20.
|
This PR has been merged and conversations have been locked. |
Why
In HA mode the action gives node B its own machine-id and hostid, then reboots it. Afterwards it read B's IDs over SSH once, with no retry. That raced with B's boot: in webui run 39251437564 the SSH connection was refused 72 s after the reboot, and the HA job failed before any test ran.
The old wait proved neither that B had gone down nor that SSH was back:
Change
unique()inha.shreads B's/proc/sys/kernel/random/boot_idbefore the reboot. It then polls over SSH every 5 s, for up to 10 minutes by the clock (SECONDS), until B answers with a different boot id. A refused connection (sshd not started yet) or a timed-out one (ConnectTimeout=10) is simply tried again. Only then does it wait for the API and read the IDs. If B doesn't come back, it fails with a clear message instead of an SSH error.shellcheck -x appliance.sh ha.sh lib.sh(the CI command) passes. The loop was also run locally against a fakessh_: refused twice, then the old boot, then a new one → it waits and returns; refused throughout → it fails with the message above once the deadline passes.