You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[fathom (gale)] — root-caused from a real red on #285, which only bumps a tool pin and had no business failing a Zephyr kernel test.
The failure
msgq_usage (qemu_cortex_m3) failed in step 4, "Install Rust + ARM target" — before any gale code ran:
curl: (35) Recv failure: Connection reset by peer
error: rustup could not choose a version of rustup to run, because one wasn't
specified explicitly, and no default is configured.
##[error]Process completed with exit code 1
The curl https://sh.rustup.rs | sh was reset at the network level, so no default toolchain was installed, and the next line (rustup target add thumbv7m-none-eabi) failed. External cause, but a fragility we own.
Two distinct problems
1. No retry, on a step that runs dozens of times per PR.
grep -rn "sh.rustup.rs" .github/workflows/*.yml -> 16 sites across 12 workflows
zephyr-tests.yml alone has four, and they feed the big matrices (~45 qemu_cortex_m3 jobs, mps2/an385, the SMP set). A single PR therefore performs dozens of unretried network installs; with several PRs open the expected number of resets stops being small. I noticed this precisely because I had four PRs in flight — my own queue pressure made a latent fragility visible.
2. curl … | sh with no pipefail can pass a TRUNCATED install.
The step has no shell: override, so it runs under Actions' default bash -e {0} — which sets -e but not-o pipefail. In curl -sSf … | sh -s -- -y, the pipeline's exit status is sh's. If curl dies mid-transfer, sh executes a partial installer and can exit 0.
This time the truncation was caught by the following line failing. That was luck, not design: a partial install that happens to leave a usable rustup shim would pass the stage and fail later somewhere far less legible — or not at all.
Proposed fix
Split download from execution, and let curl do the retrying:
--retry 5 --retry-all-errors — --retry alone does not cover (35) Recv failure; --retry-all-errors is the flag that makes connection resets retryable. This is the actual fix for the observed failure.
-o then sh — a truncated download can no longer be executed, because curl's non-zero exit stops the step before sh runs. This is the fix for the silent variant.
set -euo pipefail — belt and braces; with -o file the pipe is gone anyway.
Kill-criterion
Point the URL at a host that resets the connection (or block it) and confirm the step fails at the download, not three lines later — and that no rustup-init.sh is executed. A retry that has never been shown to catch anything is not a retry.
I have not proven the silent-truncation path has ever actually occurred here. The (35) reset is observed; the missing-pipefail hazard is read off the step definition and Actions' documented default shell. Recorded as a latent hazard, not an incident.
Deliberately not landing this yet: four PRs are already saturating the runners, and a 17-site workflow change would add another full matrix. It should land when the queue drains.
Related but separate: these steps set RUSTUP_HOME: /mnt/.rustup while sourcing /root/.cargo/env — the /root disk-exhaustion workaround. Not touched here.
[fathom (gale)] — root-caused from a real red on #285, which only bumps a tool pin and had no business failing a Zephyr kernel test.
The failure
msgq_usage (qemu_cortex_m3)failed in step 4, "Install Rust + ARM target" — before any gale code ran:The
curl https://sh.rustup.rs | shwas reset at the network level, so no default toolchain was installed, and the next line (rustup target add thumbv7m-none-eabi) failed. External cause, but a fragility we own.Two distinct problems
1. No retry, on a step that runs dozens of times per PR.
zephyr-tests.ymlalone has four, and they feed the big matrices (~45qemu_cortex_m3jobs,mps2/an385, the SMP set). A single PR therefore performs dozens of unretried network installs; with several PRs open the expected number of resets stops being small. I noticed this precisely because I had four PRs in flight — my own queue pressure made a latent fragility visible.2.
curl … | shwith nopipefailcan pass a TRUNCATED install.The step has no
shell:override, so it runs under Actions' defaultbash -e {0}— which sets-ebut not-o pipefail. Incurl -sSf … | sh -s -- -y, the pipeline's exit status issh's. If curl dies mid-transfer,shexecutes a partial installer and can exit 0.This time the truncation was caught by the following line failing. That was luck, not design: a partial install that happens to leave a usable
rustupshim would pass the stage and fail later somewhere far less legible — or not at all.Proposed fix
Split download from execution, and let curl do the retrying:
Three changes, each doing one thing:
--retry 5 --retry-all-errors—--retryalone does not cover(35) Recv failure;--retry-all-errorsis the flag that makes connection resets retryable. This is the actual fix for the observed failure.-othensh— a truncated download can no longer be executed, because curl's non-zero exit stops the step beforeshruns. This is the fix for the silent variant.set -euo pipefail— belt and braces; with-o filethe pipe is gone anyway.Kill-criterion
Point the URL at a host that resets the connection (or block it) and confirm the step fails at the download, not three lines later — and that no
rustup-init.shis executed. A retry that has never been shown to catch anything is not a retry.Scope / honesty
(35)reset is observed; the missing-pipefailhazard is read off the step definition and Actions' documented default shell. Recorded as a latent hazard, not an incident.RUSTUP_HOME: /mnt/.rustupwhile sourcing/root/.cargo/env— the/rootdisk-exhaustion workaround. Not touched here.