Skip to content

Pin a fixed UID/GID for the cloud-compose account - #41

Merged
joecorall merged 6 commits into
mainfrom
fix-cloud-compose-uid-pinning
Aug 19, 2026
Merged

Pin a fixed UID/GID for the cloud-compose account#41
joecorall merged 6 commits into
mainfrom
fix-cloud-compose-uid-pinning

Conversation

@joecorall

@joecoralljoecorall commented Aug 19, 2026

Copy link
Copy Markdown
Member

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.

@joecorall
joecorall enabled auto-merge (squash) August 19, 2026 12:05
@joecorall
joecorallforce-pushed the fix-cloud-compose-uid-pinning branch 2 times, most recently from e2ef593 to d6117bbCompareAugust 19, 2026 12:27
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.
Pins both to 2000, matching the value that was already being assigned
in practice before this became a problem.
@joecorall
joecorallforce-pushed the fix-cloud-compose-uid-pinning branch from d6117bb to da8da66CompareAugust 19, 2026 12:45
@joecorall
joecorallforce-pushed the fix-cloud-compose-uid-pinning branch from 868f319 to 26ba28eCompareAugust 19, 2026 12:55
… 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.
@joecorall
joecoralltemporarily deployed to cloud-smoke-linode August 19, 2026 13:48 — with GitHub Actions Inactive
@joecorall
joecoralltemporarily deployed to cloud-smoke-linode August 19, 2026 13:48 — with GitHub Actions Inactive
@joecorall
joecoralltemporarily deployed to cloud-smoke-digitalocean August 19, 2026 13:48 — with GitHub Actions Inactive
@joecorall
joecoralldeployed to cloud-smoke-gcp August 19, 2026 13:48 — with GitHub Actions Active
@joecorall
joecoralltemporarily deployed to cloud-smoke-linode August 19, 2026 13:48 — with GitHub Actions Inactive
@joecorall
joecoralltemporarily deployed to cloud-smoke-digitalocean August 19, 2026 13:48 — with GitHub Actions Inactive
@joecorall
joecorall merged commit c26c76b into mainAug 19, 2026
8 checks passed
@joecorall
joecorall deleted the fix-cloud-compose-uid-pinning branch August 19, 2026 14:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@joecorall