Uh oh!
There was an error while loading. Please reload this page.
Pin a fixed UID/GID for the cloud-compose account - #41
Merged
Conversation
joecorall
enabled auto-merge (squash)
August 19, 2026 12:05
joecorallforce-pushed
the
fix-cloud-compose-uid-pinning
branch
2 times, most recently
from
August 19, 2026 12:27
e2ef593 to
d6117bbCompareuseradd/groupadd previously let the cloud-compose account's UID/GID be dynamically assigned to the next free ID at creation time. On providers whose root filesystem (and therefore /etc/passwd) does not persist across boots, that ID is not stable across VM replacements: a recreated cloud-compose account can land on a different UID than the one that originally owned everything on the persistent data disk, leaving it unable to read or write its own home directory or any compose project checkout. This surfaced in production as cloud-compose-bootstrap.service failing indefinitely with git "dubious ownership" errors it misreported as a missing origin remote, because it silently swallowed the real git failure. Pins both to 2000, matching the value that was already being assigned in practice before this became a problem.
joecorallforce-pushed
the
fix-cloud-compose-uid-pinning
branch
from
August 19, 2026 12:45
d6117bb to
da8da66Comparejoecorallforce-pushed
the
fix-cloud-compose-uid-pinning
branch
from
August 19, 2026 12:55
868f319 to
26ba28eCompare… corruption The previous retry loop only wrapped terraform init. A shared plugin cache dir can let init install a package without fully re-verifying it against a given directory's lock file; a truncated or otherwise corrupted cache entry then only surfaces later, when validate or test actually loads the provider plugin binary. Since validate/test had no retry wrapper at all, a corrupted cache entry failed CI immediately and permanently for that run, in a single unretried attempt. Wrap the whole init+validate(+provider-graph+test) sequence in the same 3-attempt retry loop, purging the shared plugin cache between attempts, so a corruption discovered at any step gets a clean re-download on the next attempt instead of failing the run outright.
The retry loop fixed in the previous commit still fails identically across all 3 clean attempts in CI, which rules out a truncated/transient corrupted download: retrying a genuinely truncated fetch would not fail the same way every time. This points to the CI environment's install path consistently producing a package hash the lock file does not have at all, not intermittent corruption. On a final failure, diagnose without guessing: run terraform init -upgrade against a scratch copy of the lock file and print only the diff, so the CI log shows the exact hash line this environment needs. Restore the real lock file afterward so the diagnostic run cannot alter the committed dependency pins on its own.
It added an unconditional 4th terraform init call whenever the retry loop exhausted its attempts, which broke ci/terraform-validate-contract.sh: that contract asserts exactly three init calls and no validate/test calls when init fails every time. The diagnostic also wasn't the right layer for this - the CI failure it was meant to explain (identical corruption across three clean, cache-purged retries in the same job) already rules out truncated/transient downloads on its own; getting the exact hash needs a different approach than instrumenting this shared, contract-tested script.
Every prior attempt at this only added the hash one specific machine's `terraform init -upgrade` happened to compute (Mac, a Linux sandbox), which meant it only ever fixed whichever platform ran it. CI's Terraform lint job pins terraform_version 1.14.6 on linux_amd64, a combination none of those runs matched, so it kept failing identically and reproducibly, not from a transient corrupted download. `terraform providers lock -platform=...` fetches each named platform's official checksum from the registry API directly rather than deriving it from a live download on the calling machine, so it does not need to actually run on linux_amd64 to lock it correctly. Ran it for linux_amd64, linux_arm64, darwin_amd64, and darwin_arm64 across every directory with a tracked lock file, covering CI and both architectures of Mac and Linux contributors in one pass.
joecoralltemporarily deployed
to
cloud-smoke-linode
August 19, 2026 13:48 — with
GitHub Actions
Inactive
joecoralltemporarily deployed
to
cloud-smoke-linode
August 19, 2026 13:48 — with
GitHub Actions
Inactive
joecoralltemporarily deployed
to
cloud-smoke-digitalocean
August 19, 2026 13:48 — with
GitHub Actions
Inactive
joecoralltemporarily deployed
to
cloud-smoke-linode
August 19, 2026 13:48 — with
GitHub Actions
Inactive
joecoralltemporarily deployed
to
cloud-smoke-digitalocean
August 19, 2026 13:48 — with
GitHub Actions
Inactive
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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.
useradd/groupadd previously let the cloud-compose account's UID/GID be dynamically assigned to the next free ID at creation time. On providers whose root filesystem (and therefore /etc/passwd) does not persist across boots, that ID is not stable across VM replacements: a recreated cloud-compose account can land on a different UID than the one that originally owned everything on the persistent data disk, leaving it unable to read or write its own home directory or any compose project checkout. This surfaced in production as cloud-compose-bootstrap.service failing indefinitely with git "dubious ownership" errors it misreported as a missing origin remote, because it silently swallowed the real git failure.