fix(localstack): copy the starter script before the container starts - #11963
Open
uhla wants to merge 1 commit into
Open
fix(localstack): copy the starter script before the container starts#11963uhla wants to merge 1 commit into
uhla wants to merge 1 commit into
Conversation
The entrypoint waits only for the script to exist and then executes it, but the copy happened after the container was already running, so a poll landing mid-copy could execute an incomplete file and the container exited with code 126. containerIsCreated runs before start; labels come from an explicit inspect because getContainerInfo() is not populated yet.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
LocalStackContainerstarts the container with an entrypoint that waits for/testcontainers_start.shto exist and then executes it:but the script is copied from
containerIsStarting, i.e. once the container is already running. Thecopy publishes the filename before the contents, so a poll landing mid-copy executes an unfinished
file. The container exits with code 126, never logs
Ready., and the failure surfaces 60s later as await-strategy timeout that points away from the cause:
The container's own stderr says what really happened, but nothing surfaces it:
Existence is not readiness: during extraction the path exists while the file is still incomplete and
open for writing, so
execvefails withETXTBSY, or withEACCESon runtimes that apply the modeonly after the write. Both make a POSIX shell exit 126.
We hit this on CI at roughly 1% of builds (about 0.33% per container start) on Docker 20.10.21.
Fix
Move the copy to
containerIsCreated, whichGenericContainer.doStartcalls betweencreateCommand.exec()andstartContainerCmd, the same windowwithCopyToContainerentries alreadyuse. Nothing is running in the container there, so an incomplete script cannot be executed. This
removes the race rather than narrowing it, and does not depend on whether the runtime applies the file
mode before or after the write.
internalMarkerLabels()readgetContainerInfo(), which is not populated that early, so the labelsnow come from an explicit
inspectContainerCmd(containerId).Applied to both
org.testcontainers.localstack.LocalStackContainerand the deprecatedorg.testcontainers.containers.localstack.LocalStackContainer.Note that
containerIsStartingalso ran on the reuse path, so a reused container had the scriptre-copied over itself while running.
containerIsCreateddoes not, which is both correct (the scriptis already there, same container, same labels) and safer.
Testing
StarterScriptTestreads the script back out of the created but not yet started container andasserts it is complete. Without this change it fails with
NotFoundException: no such file or directory, so it guards the ordering rather than passing alongside it.:testcontainers-localstack:testgreen (35 tests), includingLambdaContainerLabels.shouldLabelLambdaContainers, which covers the refactored label path.containerIsStartingit fails withContainer exited with code 126, copied fromcontainerIsCreatedit starts cleanly.