fix(ci): Run LocalStack-backed Rust tests on self-hosted runners. - #2449
fix(ci): Run LocalStack-backed Rust tests on self-hosted runners.#2449jackluo923 wants to merge 1 commit into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
`tests:rust-all` starts LocalStack with `--publish <port>:4566` and connects to it over loopback. Our self-hosted runners mount the host's Docker socket, so the container `start.py` starts is a sibling on the host, and the port is published in the host's network namespace rather than the runner's, where it is unreachable from the job. The port `get-free-port.py` picks is also probed in the runner's namespace while being reserved in the host's, so it can collide with an unrelated listener or with another runner on the same machine. `clp-rust-checks` therefore targeted `GH_RUNNER_LINUX_LIGHT_X64` (`["ubuntu-24.04"]`, GitHub-hosted) to stay off the self-hosted pool. `start.py` now detects whether it is running inside a container the Docker daemon can resolve (`/.dockerenv` plus `docker inspect $(hostname)`) and, if so, starts LocalStack with `--network container:<id>` and `GATEWAY_LISTEN=0.0.0.0:<port>` instead of publishing. LocalStack then shares the job's network namespace, so loopback reaches it, nothing is published to the host, and the chosen port is probed in the namespace it is bound in. No elevated privileges are needed: `--network container:` is an ordinary network mode requiring only the socket access the runners already have. With that, `clp-rust-checks` moves to `GH_RUNNER_LINUX_HEAVY_X64` (`["self-hosted","x64","ubuntu-noble","docker"]`), which also suits the job better: `tests:rust-all` builds the workspace in release mode. GitHub-hosted runners and dev machines fail the detection and keep the existing publishing behaviour, so `AWS_ENDPOINT_URL` and the developer instructions in `components/log-ingestor/README.md` are unchanged. Address LocalStack by `127.0.0.1` rather than `localhost`: inside a container `localhost` can resolve to `::1` alone, which LocalStack's IPv4 gateway doesn't bind, so the name form fails with a connection refusal indistinguishable from the bug above. `tests/aws_config.rs` already defaulted to `127.0.0.1`; this aligns the taskfile and `create-bucket.py` with it. Also wait for `/_localstack/health` before returning from `start.py`. Nothing waited for readiness previously; `create-bucket.py` happened to paper over it via boto3 retries. Verified against a runner simulated with the host socket mounted: LocalStack was reachable on loopback with no host port published; two such runners ran concurrent LocalStacks on the same port without interfering; and the runner retained DNS and egress with LocalStack in its namespace. Publishing mode was re-verified end to end on the host through `create-bucket.py`. `ruff check`, `ruff format`, and `yamllint --strict` are clean. Co-Authored-By: Claude <noreply@anthropic.com>
c1d43ce to
1ab20d3
Compare
|
Follow-ups noted while working on this, not addressed here:
|
Description
tests:rust-allstarts LocalStack with--publish <port>:4566and connects to it over loopback. Our self-hosted runners mount the host's Docker socket, so that container is a sibling on the host: the port lands in the host's network namespace rather than the runner's, and the job can't reach it. This is why the job was pinned toGH_RUNNER_LINUX_LIGHT_X64(["ubuntu-24.04"], GitHub-hosted).start.pynow checks whether it's running inside a container the Docker daemon can resolve. If so, it starts LocalStack with--network container:<id>andGATEWAY_LISTEN=0.0.0.0:<port>instead of publishing a port, so LocalStack shares the job's network namespace and loopback reaches it. No extra privileges are needed, and because each runner has its own namespace, concurrent runners on one machine can't contend over ports.GitHub-hosted runners and dev machines fail the check and keep today's publishing behaviour, so
AWS_ENDPOINT_URLand the steps incomponents/log-ingestor/README.mdare unchanged.The job then moves to
GH_RUNNER_LINUX_HEAVY_X64(self-hosted), which suits it anyway sincetests:rust-allbuilds the workspace in release mode.Two smaller changes:
127.0.0.1rather thanlocalhost. Inside a containerlocalhostcan resolve to::1alone, which LocalStack's IPv4 gateway doesn't bind, and it fails identically to the bug above.tests/aws_config.rsalready used127.0.0.1.start.pywaits for/_localstack/healthbefore returning. Nothing waited for readiness before; boto3 retries happened to cover it.Checklist
breaking change.
Validation performed
Simulated a runner with the host Docker socket mounted, matching the
y-scope/cisetup:Also re-ran publishing mode on the host end to end through
create-bucket.py.ruff check,ruff format, andyamllint --strictare clean.