Fix A (found live on 9202): the container sampler reads docker inspect JSON — a -f template stopped at 'no entry for key Health' for every app without a healthcheck, so a healthy restore read 'not started'. Commit only.
gates / gates (push) Successful in 1m27s

This commit is contained in:
admin committed 2026-10-25 17:02:32 +01:00
1 parent 1ee0353dbd
commit 3a1f09d29f
3 files changed
+48 -11

No files matched your search

+28 -11
View File
@@ -3,6 +3,7 @@ package main
import (
"bytes"
"context"
"encoding/json"
"errors"
"flag"
"fmt"
@@ -3465,22 +3466,38 @@ func (a *stackAdapter) ContainerSamples(name string) ([]backup.ContainerSample,
if len(ids) == 0 {
return nil, nil
}
out, err = run(append([]string{"inspect", "-f", "{{.Id}} {{.State.Status}} {{.RestartCount}} {{if .State.Health}}{{.State.Health.Status}}{{end}}"}, ids...)...)
// The JSON, not a -f template: a container with no healthcheck has no State.Health, and Docker's template stops
// with „map has no entry for key Health" (measured on 9202, 2026-10-25 — every such app read „not started").
out, err = run(append([]string{"inspect"}, ids...)...)
if err != nil {
return nil, err
}
return parseContainerSamples(out)
}
// parseContainerSamples reads `docker inspect` JSON into stable-start samples; State.Health is absent for a container
// with no healthcheck (Health ""). Pinned by TestFixA_ParseContainerSamples.
func parseContainerSamples(out []byte) ([]backup.ContainerSample, error) {
var raw []struct {
ID string `json:"Id"`
RestartCount int `json:"RestartCount"`
State struct {
Status string `json:"Status"`
Health *struct {
Status string `json:"Status"`
} `json:"Health"`
} `json:"State"`
}
if err := json.Unmarshal(out, &raw); err != nil {
return nil, fmt.Errorf("docker inspect: %w", err)
}
var res []backup.ContainerSample
for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") {
f := strings.Fields(line)
if len(f) < 3 {
continue
for _, c := range raw {
cs := backup.ContainerSample{ID: c.ID, Running: c.State.Status == "running", RestartCount: c.RestartCount}
if c.State.Health != nil {
cs.Health = c.State.Health.Status
}
n, _ := strconv.Atoi(f[2])
c := backup.ContainerSample{ID: f[0], Running: f[1] == "running", RestartCount: n}
if len(f) > 3 {
c.Health = f[3]
}
res = append(res, c)
res = append(res, cs)
}
return res, nil
}