fix(landscape): accept an empty run body; pin the builder's Alpine release

POST /landscape/runs documents an optional body, but DecodeJSON returned
io.EOF on an empty one and the handler turned that into 400 — breaking the
most common call, an all-defaults run. decodeRunRequest now treats io.EOF as
the zero request; a malformed body is still 400.

The Dockerfile's Alpine ABI coupling was enforced only by a comment: a
floating golang:1.26-alpine builder against a pinned alpine:3.24 runtime
would build green and die at startup on a libgdal soname mismatch as soon as
the Go image rolls forward. Both stages are now pinned to 3.24.

Also: the route-mount test walks the router so all six routes are asserted
(GET /slots and GET /results included), and the spec documents the 404 those
two return when migration 00011's seeded groups are absent.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-09-05 14:22:26 +05:00
parent ad3c9fbdcd
commit 6aec00ee29
4 changed files with 129 additions and 26 deletions

View File

@@ -1,5 +1,5 @@
# Build context is the repo root: docker build -f build/package/Dockerfile .
FROM golang:1.26-alpine AS builder
FROM golang:1.26-alpine3.24 AS builder
# godal (GDAL bindings) needs cgo, a C/C++ toolchain and the GDAL headers.
# g++ is required: parts of the binding compile as C++ against GDAL's headers.
@@ -13,8 +13,11 @@ RUN go mod download
COPY . .
RUN CGO_ENABLED=1 GOOS=linux go build -trimpath -o /out/gis ./cmd/gis
# Must match the builder's Alpine release (golang:1.26-alpine is Alpine 3.24):
# an older base ships a different libgdal soname and the binary will not start.
# Must stay on the same Alpine release as the builder — hence the pinned
# `golang:1.26-alpine3.24` above rather than the floating `-alpine` tag. A
# mismatch ships a different libgdal soname, and the image still builds green
# while the binary dies at startup with "libgdal.so.NN: No such file".
# Bump both lines together.
FROM alpine:3.24
# gdal: shared library for godal (raster math in the worker).