Repository navigation
fix(cli): tag an image's Features build per workspace in up - #72
Merged
Merged
Conversation
`up` of an image configuration with Features tagged the build `<image>-features`, so every workspace on the same image shared one tag. Concurrent runs retagged it under each other and could start a container from another workspace's image, with that workspace's lifecycle commands in its metadata label. The official CLI tags it `vsc-<folder>-<hash>-features` (getFolderImageName in extendImage), and `build` already did; `up` now does too. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Compose names its project and images after the workspace's basename, which t.TempDir makes 001 in every run; the dockerignore test used a fixed tag; and the build/up/exec tests used the repository's fixture folder, so runs from one checkout shared a container. Workspaces now have a unique basename, the fixtures are copied into one, and the dockerignore image name is unique. Co-Authored-By: Claude Opus 5.5 <[email protected]>
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.
Cause
TestE2E_CABundle/containerfailed when another run of it shared the Docker daemon:upran a postCreateCommand pointing at the other run's TLS server and nonce.It isn't the workspace basename.
folderImageNamehashes the full path (vsc-<basename>-<sha256(path)>), the same as TSgetFolderImageName, andt.TempDirpaths differ between runs. The collision comes from the product:upof an image configuration with Features calledextendImageWithFeatureswith no names, so it tagged the build<image>-features, for examplemcr.microsoft.com/devcontainers/base:ubuntu-features. Every workspace on that image shared the tag. One run's build retagged it before the other randocker run, so the container started from the wrong image and its metadata label carried the wrong lifecycle commands.TS tags it
${getFolderImageName(common)}-features(containerFeatures.ts,extendImage), and ourbuildalready usesfolder+"-features". Onlyupdiverged.Fix
fix(cli):fromImagepassesfolderImageName(workspaceFolder) + "-features", which matches TS. The hermetic regression testTestUpImageFeaturesTagsFolderImagefails before the change (tags = [alpine:3-features]) and passes after. There's a migration note indocs/migration.mdbecause image tags are a public contract.test(cli): three other e2e tests could collide under concurrency:TestE2E_ComposeBuildLabel: Compose takes the project and image name from the workspace basename, andt.TempDirmakes it001in every run.TestE2E_SiblingDockerignore: used the fixed tage2e-dockerignore:test, which another run's cleanup could remove.TestE2E_BuildUpExec_*: used the repo fixture folder directly, so runs from one checkout shared a container (both match it by itslocal_folderlabel).Workspaces now get a unique basename (
ws-<random>), the fixtures are copied into one, and the dockerignore image name is unique.Evidence
Two concurrent
TestE2E_CABundleruns (separate TMPDIR):172.17.0.5, nonce03cedd…) failed incontainerwithpostCreateCommand … https://172.17.0.8:8443/5640088059827986, which is run 2's server and nonce. Both logs shownaming to mcr.microsoft.com/devcontainers/base:ubuntu-features.vsc-ws-25330079-eb42…-featuresandvsc-ws-2525456359-b1dd…-features.Two concurrent full
-run '^TestE2E'suites after the change: both pass.Validation (local)
go vet ./internal/cli/,go tool task lint: pass.go tool task test:race: pass withTMPDIR=/dev/shm/…. With the default/tmp,TestOpen*andTestComputeWorkspaceConfigOutsideARepositoryfail before and after this change, because this machine has a stray empty/tmp/.git.go tool task test:e2e: all 13 pass.go tool task parity:contract: 114 matched. Tworead-configuration.features-configuration-local-feature-*cases fail identically without this change, for local environment reasons (the same/tmp/.git, or unnormalized paths when TMPDIR is outside/tmp).PARITY_COMMAND=up task parity:runtime:up.image-with-features-successandup.image-with-git-feature-successmatched. The 22 failures don't go through this path; they're/tmp/parity-*workspaces under the stray/tmp/.gitplus cleanup timeouts. I'm leaving runtime parity to CI.🤖 Generated with Claude Code