Debian 13 runtime with restic 0.18.1 pinned outside the OS; restic assumptions re-proven; felhom-samba 1.2.0 (R-1105, R-972)
gates / gates (push) Successful in 49s
gates / gates (push) Successful in 49s
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// R-1105: restic is pinned OUTSIDE the OS. Until v0.323.0 it came from the runtime's apt list, so the
|
||||
// version was „whatever Debian ships" — a Debian 12 → 13 base move would have swapped restic 0.14.0 for
|
||||
// 0.18.0 under the off-site code with nobody choosing it. The consequences pinned here:
|
||||
// - the version is one explicit ARG, and each architecture's checksum is pinned beside it;
|
||||
// - the fetch checks restic's signature (vendored key, no keyserver) AND both checksums;
|
||||
// - the runtime takes restic ONLY from that stage — no apt package can bring a second one;
|
||||
// - every base image is pinned by digest, and the Docker repo's codename is read from the image.
|
||||
func TestR1105_ResticIsPinnedOutsideTheOS(t *testing.T) {
|
||||
raw, err := os.ReadFile("../../Dockerfile")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
src := string(raw)
|
||||
// Stages, split on FROM, with `\`-continued lines joined so an apt list reads as one command.
|
||||
joined := strings.ReplaceAll(src, "\\\n", " ")
|
||||
var stages []string
|
||||
for _, part := range regexp.MustCompile(`(?m)^FROM `).Split(joined, -1)[1:] {
|
||||
stages = append(stages, "FROM "+part)
|
||||
}
|
||||
if len(stages) < 3 {
|
||||
t.Fatalf("expected a builder, a restic and a runtime stage, found %d stages", len(stages))
|
||||
}
|
||||
var fetch string
|
||||
for _, s := range stages {
|
||||
if regexp.MustCompile(`^FROM \S+ AS restic\b`).MatchString(s) {
|
||||
fetch = s
|
||||
}
|
||||
}
|
||||
if fetch == "" {
|
||||
t.Fatal("no `AS restic` stage: restic is no longer fetched as a pinned release binary")
|
||||
}
|
||||
runtime := stages[len(stages)-1]
|
||||
|
||||
if m := regexp.MustCompile(`ARG RESTIC_VERSION=(\d+\.\d+\.\d+)\s`).FindStringSubmatch(fetch); m == nil {
|
||||
t.Error("ARG RESTIC_VERSION=X.Y.Z is missing — the version must be an explicit decision")
|
||||
}
|
||||
for _, arch := range []string{"AMD64", "ARM64"} {
|
||||
if !regexp.MustCompile(`ARG RESTIC_SHA256_` + arch + `=[0-9a-f]{64}\s`).MatchString(fetch) {
|
||||
t.Errorf("no pinned sha256 for %s", arch)
|
||||
}
|
||||
}
|
||||
for _, want := range []string{
|
||||
"COPY third_party/restic/restic-release-key.asc",
|
||||
"gpgv --keyring", // SHA256SUMS is restic's, signed
|
||||
`SHA256SUMS | sha256sum -c -`, // the download matches the published sum
|
||||
`echo "${want} ${f}" | sha256sum -c -`, // ...and the sum pinned in this file
|
||||
} {
|
||||
if !strings.Contains(fetch, want) {
|
||||
t.Errorf("the restic stage no longer does %q", want)
|
||||
}
|
||||
}
|
||||
if _, err := os.Stat("../../third_party/restic/restic-release-key.asc"); err != nil {
|
||||
t.Errorf("the vendored release key is missing: %v", err)
|
||||
}
|
||||
|
||||
if !strings.Contains(runtime, "COPY --from=restic /usr/local/bin/restic /usr/local/bin/restic") {
|
||||
t.Error("the runtime does not take restic from the pinned stage")
|
||||
}
|
||||
aptRe := regexp.MustCompile(`apt-get install[^&]*`)
|
||||
for _, inst := range aptRe.FindAllString(runtime, -1) {
|
||||
if regexp.MustCompile(`\srestic(\s|$)`).MatchString(inst) {
|
||||
t.Errorf("the runtime's apt list installs restic — a second, OS-chosen restic: %q", strings.Join(strings.Fields(inst), " "))
|
||||
}
|
||||
}
|
||||
|
||||
for _, from := range regexp.MustCompile(`(?m)^FROM (\S+)`).FindAllStringSubmatch(src, -1) {
|
||||
if !strings.Contains(from[1], "@sha256:") {
|
||||
t.Errorf("base image %s is not pinned by digest", from[1])
|
||||
}
|
||||
}
|
||||
if regexp.MustCompile(`download\.docker\.com/linux/debian (bookworm|trixie|forky)`).MatchString(src) {
|
||||
t.Error("the Docker apt repo codename is hard-coded — it must come from /etc/os-release (VERSION_CODENAME)")
|
||||
}
|
||||
if !strings.Contains(runtime, "${VERSION_CODENAME}") {
|
||||
t.Error("the Docker apt repo line does not read VERSION_CODENAME")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user