Skip to content

build: upgrade Go toolchain to 1.27.1, retain Alpine 3.20 runtime - #52

Merged
dborup merged 1 commit into
masterfrom
codex/go-1271-toolchain
Sep 14, 2026
Merged

dborup merged 1 commit into
masterfrom
codex/go-1271-toolchain

Conversation

@dborup

@dborup dborup commented Sep 14, 2026 •

Copy link
Copy Markdown
Owner

Formål og scope

Genoptager Go-only-halvdelen af #22 (bump-docker-to-alpine-3.24), som kombinerede en Go-toolchain-opgradering med en Alpine-runtime-opgradering. Efter beslutning gennemføres Go-opgraderingen først, isoleret; Alpine-runtime-opgraderingen (3.20 → 3.24) vurderes separat, senere. #22 og dens eksterne featurebranch er ikke rørt.

Præcis tre-fils-scope:

  • Dockerfile
  • Dockerfile.go
  • .github/workflows/deploy.yml

Vigtig skelnen: Go-builder-imaget kører selv på Alpine 3.24 (golang:1.27.1-alpine3.24) — det er byggemiljøet, ikke den færdige container. Den færdige runtime forbliver Alpine 3.20 (FROM alpine:3.20, uændret i begge Dockerfiles). "Ingen Alpine-ændring" ville være misvisende; det korrekte er: builderens Alpine-version ændres, runtime-Alpine gør ikke.

Ingen ændringer af go.mod/go.sum, applikationskode, database eller config.

Baseline, master og verificeret integration

Branchens oprindelige base 6b70e94a55195d26a8d3e4b1133f3e54ce2dd4d7
Aktuel master (genbekræftet) 76ce1a6819609acf4199dd979d97390f3fcb565e
Feature-head (1 commit) cc8e3ad3336923f227aeda631accbe9ff8257ea0
Beregnet integrations-tree-OID (git merge-tree, genberegnet 2 gange, ingen refs ændret) dabd49999d77b58e2f21f8978fc9e84c3e343caf

Bemærk: branch-træet og integrationstræet er ikke identiske — integrationen indeholder også #30's ændringer (public/index.html, test-all.sh, test-issue-1890-og-url.js, én linje i deploy.yml). De 15 Go-modul-mapper samt Dockerfile/Dockerfile.go er verificeret byte-for-byte identiske mellem de to træer (sti-bundet: git-mode + git-oid sammenlignet direkte mod hver fil på disk, ikke kun et hash-multisæt) — det er derfor, tidligere Go-testresultater kan genbruges for netop de moduler, men det gør ikke de to træer identiske som helhed.

Diff mod aktuel master (fra integrationstræet) indeholder udelukkende de tre filer ovenfor, 8 insertions/8 deletions. Ingen hemmeligheder eller utilsigtede ændringer fundet ved gennemgang af den fulde diff.

Go-builder

golang:1.22-alpine → golang:1.27.1-alpine3.24, pinnet på digest:
sha256:cf6fca6641884b8433441b2b0652976f975e1d0fdd26d177eaaf8596087f3125 (matcher også den flydende 1.27-alpine3.24-tag, dvs. ingen nyere 1.27.x-patch findes).

Forhold til #22

Dette er Go-only-delen af det, #22 forsøgte at gøre på én gang. Alpine-runtime-opgraderingen (3.20 → 3.24) vurderes i en separat, senere opgave. Ingen closing-keyword for #22 er brugt her.

Bevaret fra #30 og #51


Rettelse: præcisering af de tre ingestor-race-fund (fra rå logs)

En tidligere version af denne beskrivelse formulerede sig upræcist om, hvorvidt alle tre kendte fejl blev set i den samme, ene fulde -race-kørsel. Genfundet direkte fra de originale JSON-testlogs, uden at genkøre noget:

# Kørsel Starttidspunkt (UTC) Træ Platform Go-version Kommando Konkrete fejlede tests (denne ene kørsel)
1 Fuld suite 2026-09-14 09:34:58 dabd4999… linux/arm64 (native) go1.22.12 go test -race -count=1 -json -timeout 25m ./... (i cmd/ingestor) TestBackfillTxLastSeen_ResolvesFromMaxObservationTimestamp, TestHandleNeighborsReportInvalidTimestampLogsEvenWithoutScopeEvidence, TestStatsFileWriter_SampledAtMatchesProcIOSampledAt (3 af 3)
2 Fuld suite 2026-09-14 09:40:59 dabd4999… linux/arm64 (native) go1.27.1 samme kommando TestBackfillTxLastSeen_ResolvesFromMaxObservationTimestamp, TestStatsFileWriter_SampledAtMatchesProcIOSampledAt (kun 2 af 3 — InvalidTimestampLogs optrådte ikke i denne ene kørsel)
3 Målrettet gentagelse 2026-09-14 09:48:22 dabd4999… linux/arm64 (native) go1.22.12 go test -race -count=50 -run '^TestHandleNeighborsReportInvalidTimestampLogsEvenWithoutScopeEvidence$' -v . 3/50 FAIL, 5 data race-rapporter
4 Målrettet gentagelse 2026-09-14 09:48:36 dabd4999… linux/arm64 (native) go1.27.1 samme kommando 3/50 FAIL, 5 data race-rapporter
5 Målrettet 09:34:58 / 09:40:59 (samme containere som 1/2) dabd4999… linux/arm64 (native) begge go test -race -count=20 -run '^TestPruneOldNeighborMetrics$' . 0/20 FAIL på begge

Svar på det konkrete spørgsmål: ja, der blev faktisk kørt to separate, ægte fulde suite-kørsler (kørsel 1 og 2, én pr. toolchain) — det er ikke en sammenblanding. Kørsel 2 (1.27.1, fuld suite, count=1) viste kun 2 af de 3 kendte fejl; InvalidTimestampLogs-racen manglede i netop denne ene kørsel. For ikke fejlagtigt at konkludere "løst på 1.27.1" ud fra ét enkelt fravær, blev den efterfølgende kørt separat og målrettet (kørsel 3+4, -count=50) — her optrådte den lige så ofte på begge toolchains (3/50). En tidligere formulering listede begge races som "to distinkte data races" i forlængelse af den fulde kørsel uden at gentage denne skelnen tydeligt nok — det er rettet her.

Skelnet mellem assertion, data race og gentagelsesrate:

  • TestBackfillTxLastSeen_ResolvesFromMaxObservationTimestamp: almindelig assertion-fejl (tx_last_seen_backfill_test.go:63: last_seen = 100, want 300), identisk tekst, set i BEGGE fulde kørsler (1 og 2).
  • TestStatsFileWriter_SampledAtMatchesProcIOSampledAt: data race, set i begge fulde kørsler.
  • TestHandleNeighborsReportInvalidTimestampLogsEvenWithoutScopeEvidence: data race, set i den fulde kørsel for 1.22.12 (kørsel 1), ikke set i den fulde kørsel for 1.27.1 (kørsel 2), men reproduceret ved målrettet gentagelse på begge (kørsel 3+4).

Korrekt statistisk formulering: racen i TestHandleNeighborsReportInvalidTimestampLogsEvenWithoutScopeEvidence reproduceres på begge toolchains. Der blev observeret 3 fejl i 50 kørsler på hver; ingen forskel blev observeret i denne stikprøve. Det udelukker ikke en forskel i fejlhyppighed. Samme observerede fejlrate beviser ikke statistisk ækvivalens.

Ingen af de tre rettes i denne PR (uden for scope: kun Go-toolchain-opgradering). Ingen lange suiter er genkørt for at få denne rapport til at stemme — ovenstående er udelukkende genfundet fra de allerede eksisterende logs.


Ny verifikation: det præcise integrationstræ bygget og runtime-testet, arm64 + amd64

Eksport verificeret sti-bundet (ikke kun hash-multisæt): for alle 1196 filer i integrationstræet er git-mode, git-sti og git-oid sammenlignet direkte mod den tilsvarende fil på disk — 0 afvigelser. Samme kontrol udført for et separat eksporteret eksakt-master-træ (baseline).

Build (primær Dockerfile; Dockerfile.go behandlet separat nedenfor):

Variant Platform Native/emuleret Builder-digest Runtime-digest Image-ID Arkitektur (docker inspect) Binær-arkitektur (file) Go-version (go version -m)
Baseline (eksakt master) linux/arm64 native golang:1.22-alpine@sha256:1699c100… alpine:3.20@sha256:d9e853e8… sha256:f28762d9… arm64 ELF ARM aarch64 go1.22.12
Baseline linux/amd64 emuleret (QEMU, indbygget i Docker Desktop, ingen ny installation/registrering foretaget) samme samme sha256:ae1deab5… amd64 ELF x86-64 go1.22.12
Candidate (eksakt integrationstræ) linux/arm64 native golang:1.27.1-alpine3.24@sha256:cf6fca66… alpine:3.20@sha256:d9e853e8… sha256:2314cbdd… arm64 ELF ARM aarch64 go1.27.1
Candidate linux/amd64 emuleret samme samme sha256:ee122894… amd64 ELF x86-64 go1.27.1

Alle 12 binærer (server/ingestor/decrypt × 4 image-varianter) verificeret ved faktisk file-ELF-arkitektur og go version -m — ikke kun Docker-labels. Build-arg-metadata (APP_VERSION=pr52-verify, GIT_COMMIT=testonly-not-a-real-commit) er tydeligt markeret testdata, ikke feature-head-SHA'en, for ikke at fremstille et testbuild som integrationens rigtige identitet.

Runtime-pakker: apk list -I + /etc/alpine-release identiske mellem baseline og candidate, både arm64 og amd64 (kun forventede aarch64/x86_64-pakkesuffiks-forskelle mellem arkitekturer).

Dockerfile.go: bygger fortsat ikke, identisk fejl på begge varianter i denne kørsel (go mod download: reading /internal/dbconfig/go.mod: open /internal/dbconfig/go.mod: no such file or directory) — dokumenteret, ikke rettet.

Runtime-smoke (fire konfigurationer: baseline/candidate × arm64/amd64), friske syntetiske databaser, --network none, ingen rigtig MQTT/database:

Kontrol baseline arm64 candidate arm64 baseline amd64 (emuleret) candidate amd64 (emuleret)
Health /api/stats 4s 3s 4s 4s
Ingestor abonnerer på lokal mock-broker (containerens egen mosquitto) 1s 1s 1s 1s
og:url-meta i serveret HTML fraværende fraværende fraværende fraværende
MQTT-fixture (1 ACK-pakke) → forventet DB-write tx=1, obs=1, hash/type/route korrekt identisk identisk identisk
DB-integritet ok ok ok ok
Fatal error / SIGSEGV / SIGBUS / OOM ingen ingen ingen ingen
Rent stop 5.23s, exit 0 5.28s, exit 0 5.28s, exit 0 5.29s, exit 0

Alle fire konfigurationer gav identiske resultater for det kontrollerede MQTT-fixturesæt. og:url-tjekket bekræfter kun, at #30's fix er bagt ind i den servererede HTML på begge — da baseline er eksakt master (som allerede indeholder #30), er dette ikke en candidate-specifik forskel, men en bekræftelse af, at Go-opgraderingen ikke regredierer den.

Skelnet eksplicit: "processen startede" og "processen svarede korrekt på API/DB-niveau" er verificeret adskilt — sidstnævnte er det, der faktisk er testet ovenfor (ikke kun opstart). amd64-emulering fungerede uden nye systemændringer; intet binfmt/QEMU blev installeret eller registreret af denne opgave — Docker Desktop leverer det indbygget.

Kendte begrænsninger — fortsat ikke løst, ikke skjult

Status

DRAFT — ikke klar til merge. Afventer review af ovenstående, herunder de kendte, dokumenterede baseline-fejl.

🤖 Generated with Claude Code

Resumes the Go-only half of PR #22 (bump-docker-to-alpine-3.24), which
combined a Go toolchain bump with an Alpine runtime bump. Per decision,
the Go bump proceeds first here; the Alpine runtime bump is deferred to
a separate, later task. PR #22 and its external feature branch are not
touched.

- Dockerfile / Dockerfile.go builder stage:
  golang:1.22-alpine -> golang:1.27.1-alpine3.24, pinned by digest
  (sha256:cf6fca6641884b8433441b2b0652976f975e1d0fdd26d177eaaf8596087f3125,
  re-verified live against the registry immediately before this commit).
- .github/workflows/deploy.yml: all three actions/setup-go steps
  (go-test, e2e-test, release-artifacts) go-version '1.22' -> '1.27.1',
  step names updated to match.
- Runtime base (`FROM alpine:3.20`, Dockerfile line 60 / Dockerfile.go
  line 24) is untouched. go.mod/go.sum, application code, database
  schema and config are untouched.
- #51's fork-guard `if:` conditions in deploy.yml are untouched;
  cmd/server/fork_guard_workflow_test.go and
  release_fast_path_workflow_test.go both pass unmodified against the
  edited deploy.yml.

Verified in isolation (origin/master @ 6b70e94, Docker Desktop
27.4.0/BuildKit, linux/arm64 native):
- go build + go vet clean across all 15 Go modules, both golang:1.22.12
  and golang:1.27.1 toolchains (bookworm images, for glibc/-race parity
  with CI).
- cmd/server full suite incl. -race: PASS on both toolchains.
- TestPruneOldNeighborMetrics (#33) alone, -race -count=10: PASS on
  both toolchains, 0 races -- the pruning-test fix holds under 1.27.1.
- cmd/ingestor repeated 10x per toolchain (no -race): 5/10 failed on
  BOTH 1.22.12 and 1.27.1, every failure a member of the pre-existing,
  already-documented TestBackfillTxLastSeen_* family from #33. Same
  rate, same tests, on both toolchains -- not introduced or worsened by
  this change. Not fixed here (out of scope).
- Native arm64 image build (both variants) + amd64 cross-compile
  (builder-stage export only, NOT a runtime test) succeed; all 6
  binaries carry the correct go version via `go version -m`
  (go1.22.12 baseline / go1.27.1 candidate) and CGO_ENABLED=0.
- Runtime base identical byte-for-byte between variants: `apk list -I`
  and /etc/alpine-release match exactly (alpine 3.20.10).
- arm64 runtime smoke (both variants, --network none, no MQTT/DB
  traffic): all 4 supervisor programs (mosquitto, ingestor, server,
  caddy) reach RUNNING, /api/stats responds 200 with engine:"go",
  corescope-decrypt --version runs, clean stop (~6s, exit 0, no OOM).
- Dockerfile.go fails identically on both variants at `go mod download`
  (missing internal/ COPY lines) -- pre-existing (#33-documented),
  unrelated to Go version, not fixed here.
- gofmt: no .go files touched. git diff --check: clean. deploy.yml:
  valid YAML.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@dborup
dborup marked this pull request as ready for review September 14, 2026 11:27
@dborup
dborup merged commit c5d472b into master Sep 14, 2026
5 of 6 checks passed
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