A doctor command looks at the machine and says what is wrong. doctor
holds the checks and writes them:
✓ Docker Engine: 28.1.1 (>= 25.0)
✗ cgroupv2: not mounted (sind requires cgroupv2)
! inotify: max_user_instances 128 (optional)
Boot with the unified cgroup hierarchy.
Raise the limit: sudo sysctl fs.inotify.max_user_instances=1024
| Name | What it does |
|---|---|
doctor.Check | one check: name, status, detail, remediation |
doctor.Status | doctor.StatusOK, doctor.StatusWarning, doctor.StatusFailed |
doctor.Write | the checks for a person, with the remediations |
doctor.Worst, doctor.Count | sum up a list, for the exit status |
const pull = "Pull the node image:\n\ndocker pull ghcr.io/gsi-hpc/sind-node"
checks := []doctor.Check{
{Name: "Docker Engine", Status: doctor.StatusOK, Detail: "28.1.1 (>= 25.0)"},
{Name: "node image", Status: doctor.StatusFailed, Detail: "not found\x1b[2J", Remediation: pull},
{Name: "inotify", Status: doctor.StatusWarning, Detail: "max_user_instances 128 (optional)"},
{Name: "sshuttle", Status: doctor.StatusWarning, Detail: "not in PATH"},
}
if err := doctor.Write(os.Stdout, checks); err != nil {
fmt.Println(err)
}
failed, warned := doctor.Count(checks)
fmt.Printf("\n%d checks, %d failed, %d warnings\n", len(checks), failed, warned)
if doctor.Worst(checks) == doctor.StatusFailed {
fmt.Println("exit status 1")
}✓ Docker Engine: 28.1.1 (>= 25.0)
✗ node image: not found\x1b[2J
! inotify: max_user_instances 128 (optional)
! sshuttle: not in PATH
Pull the node image:
docker pull ghcr.io/gsi-hpc/sind-node
4 checks, 1 failed, 2 warnings
exit status 1doctor/example_test.go. CI runs it and checks its output.Fixed interfaces#
The status words, the JSON keys name, status, detail and
remediation, and the text that Write writes (decision 38). The
checks, their texts and the exit status are the program’s.