Skip to content

fix(host-provisioning): apt retry, drop gpg, AWS CLI v2, atomic writes (26.04 live-verified)#178

Merged
pedromvgomes merged 3 commits into
mainfrom
fix/apt-update-lock-gpg
Jul 7, 2026
Merged

fix(host-provisioning): apt retry, drop gpg, AWS CLI v2, atomic writes (26.04 live-verified)#178
pedromvgomes merged 3 commits into
mainfrom
fix/apt-update-lock-gpg

Conversation

@pedromvgomes

@pedromvgomes pedromvgomes commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Host-provisioning fixes for the self-hosted-Postgres + observability deploy, validated end-to-end on a live Ubuntu 26.04 host (resolute, coreutils 9) — the actual deploy target — by rendering the real install scripts, running the 5 apt installs concurrently, and driving the full Postgres cluster flow to a live psql connection.

Fixed

  1. apt-get update lists-lock race. -o DPkg::Lock::Timeout doesn't cover apt-get update's lists lock — new internal/aptlock.UpdateCmd retries it. Live: survives 5 concurrent installs.
  2. gpg: cannot open '/dev/tty'. Dropped gpg --dearmor — install the armored .asc key and use apt signed-by directly. Live: keyrings valid, no tty error.
  3. sudo -E ignored by the deploy sudoers → pass DEBIAN_FRONTEND on the command line. Live: sudo VAR=val works under the real NOPASSWD:ALL sudoers.
  4. awscli apt package gone from Ubuntu 24.04+ → install the official AWS CLI v2 bundle. Live: aws-cli/2.35.16.
  5. install /dev/stdin over an existing file fails on coreutils 9 (Ubuntu 26.04)"install: No such file or directory" — which the Postgres config write always hits (initdb pre-creates postgresql.conf), aborting the cluster apply. The postgres/otelcol/dbbackup writeFileScript helpers now stage to a temp then atomic mv (the pattern internal/remote already used). Live: cluster comes up.

Validated live on 26.04 (the real target)

  • All 5 apt installs pass concurrently (0 failures); .asc keyrings; AWS CLI v2.
  • Postgres cluster: install → initdb → apply → **active**, PGDATA 0700, psql connects — PostgreSQL 17.10 (pgdg26.04 build).
  • Repo pre-checks: PGDG resolute-pgdg has postgresql-17; nginx.org resolute mainline has nginx + nginx-module-acme.

(An initdb "invalid locale" error during testing was a test artifact — the local ssh client forwarding an ungenerated LANG; the real Go-SSH deploy doesn't forward it.)

Tests

aptlock (retry + bash -n); nginx install (no gpg/-E, .asc, retry); Postgres install (.asc, retry) + writeFileScript (temp+mv); dbbackup (AWS CLI v2, temp+mv); otelcol (temp+mv). CGO_ENABLED=0 go build, go test -race ./..., golangci-lint all clean.

Merge Commit Message

fix(host-provisioning): apt-update retry, drop gpg, AWS CLI v2, atomic file writes

Live-verified on Ubuntu 26.04 (the deploy target). apt-get update's lists lock
isn't covered by DPkg::Lock::Timeout — retry it. gpg --dearmor fails with no tty —
use the armored .asc via apt signed-by. sudo -E is ignored — pass DEBIAN_FRONTEND
on the command line. awscli is gone from Ubuntu 24.04+ — install AWS CLI v2. And
`install /dev/stdin` over an existing file fails on coreutils 9 — stage to a temp
then atomic mv (postgres/otelcol/dbbackup), fixing the Postgres cluster apply.

https://claude.ai/code/session_015CmCU1fcbVKUR2k1dquEWV

…or (v5 deploy)

The re-deploy still failed on two host-provisioning issues the earlier lock/keyring
work didn't fully cover:

- `E: Could not get lock /var/lib/apt/lists/lock`. `-o DPkg::Lock::Timeout` does NOT
  cover `apt-get update`'s lists lock on Ubuntu 24.04's apt, so the ~4 concurrent
  per-host installs (ingress + mesh nginx, Postgres, awscli) still raced it. New
  `internal/aptlock.UpdateCmd` retries `apt-get update` until the lock frees; used
  by the nginx, Postgres, and backup installs.
- `gpg: cannot open '/dev/tty'`. `sudo gpg --dearmor` fails on a host with no
  controlling tty. Drop gpg entirely — install the ARMORED signing key (.asc) and
  reference it via apt's signed-by (apt reads armored keys directly). Applied to the
  nginx and Postgres keyrings.
- The nginx install used `sudo -E apt-get`, which the host sudoers ignores ("'-E' is
  ignored"), so DEBIAN_FRONTEND=noninteractive never reached apt (debconf fell back
  to a Teletype frontend). Pass it on the sudo command line instead, matching the
  other installs (incl. the mesh openssl install).

Regression tests: aptlock retry + bash -n; nginx install (no gpg / no -E, .asc key,
retry update); Postgres install (.asc key, no gpg, retry update).

Claude-Session: https://claude.ai/code/session_015CmCU1fcbVKUR2k1dquEWV
…m Ubuntu 24.04)

Verified on a live Ubuntu 24.04 host: `apt-get install awscli` fails with
"Package 'awscli' has no installation candidate" — the package was dropped from
noble. Install the official AWS CLI v2 bundle instead (self-contained, current,
supported), extracted with unzip; `aws/install --update` is idempotent.

Caught by an end-to-end run of the rendered install scripts against a throwaway
Hetzner host — which also confirmed the retry-update survives 5-way apt
contention, the armored .asc keyrings work with no gpg tty error, `sudo VAR=val`
works under the deploy sudoers, and the Postgres cluster initdb+start comes up
with 0700 PGDATA and accepts a psql connection.
@pedromvgomes pedromvgomes changed the title fix(host-provisioning): retry apt-get update on lock + drop gpg dearmor (v5 deploy) fix(host-provisioning): apt-update retry, drop gpg dearmor, AWS CLI v2 (v5 deploy, live-verified) Jul 7, 2026
…stdin fails on 26.04)

Verified on a live Ubuntu 26.04 (resolute, coreutils 9) host: `sudo install -m
<mode> /dev/stdin <path>` fails "install: No such file or directory" when the
target ALREADY EXISTS — which the Postgres config write always hits, because
initdb pre-creates postgresql.conf/pg_hba.conf. That aborted the cluster apply, so
the postmaster never started.

Switch the postgres/otelcol/dbbackup writeFileScript helpers to the same
stage-then-atomic-mv pattern already used in internal/remote: base64 -d | tee to a
mktemp temp, chmod (+chown) the temp, then mv into place. A 0600 file is never
briefly world-readable and the replace is atomic. (remote.go already did this.)

Caught by re-running the end-to-end install-script suite on 26.04 — the ACTUAL
deploy target (24.04 passed because its older install accepts /dev/stdin over an
existing file). That run also confirmed on 26.04: all 5 apt installs pass
concurrently, .asc keyrings, AWS CLI v2, and the full Postgres cluster now comes up
(active, PGDATA 0700, psql connects, pgdg26.04 build).
@pedromvgomes pedromvgomes changed the title fix(host-provisioning): apt-update retry, drop gpg dearmor, AWS CLI v2 (v5 deploy, live-verified) fix(host-provisioning): apt retry, drop gpg, AWS CLI v2, atomic writes (26.04 live-verified) Jul 7, 2026
@pedromvgomes pedromvgomes merged commit 5164158 into main Jul 7, 2026
2 checks passed
@pedromvgomes pedromvgomes deleted the fix/apt-update-lock-gpg branch July 7, 2026 18:41
Sign up for free to 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