Skip to content

Commit 2206d39

Browse files
feat(doctor): X6 (part) — dns /etc/hosts probe (spec 05/13) (#35)
Extend the doctor matrix with a best-effort `dns (/etc/hosts)` probe: when the current dir is a workspace with a configured Caddy proxy, it diffs the proxy route hosts against the marker-fenced /etc/hosts block (dns.Missing) and warns with `sudo devstack dns setup` when any are absent. Non-fatal (local routing is opt-in); skipped entirely outside a proxy workspace. Pairs with the trust probe to complete the M5 self-verification in doctor; the shared-ledger probe + safe --fix remain for the rest of X6. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 48efb6c commit 2206d39

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

internal/cli/doctor.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import (
77

88
"github.com/spf13/cobra"
99

10+
"github.com/open-source-cloud/devstack/internal/config"
11+
"github.com/open-source-cloud/devstack/internal/dns"
1012
"github.com/open-source-cloud/devstack/internal/docker"
13+
"github.com/open-source-cloud/devstack/internal/proxy"
1114
"github.com/open-source-cloud/devstack/internal/state"
1215
"github.com/open-source-cloud/devstack/internal/trust"
1316
"github.com/open-source-cloud/devstack/internal/xdg"
@@ -135,6 +138,26 @@ func runDoctor(cmd *cobra.Command) []docker.Check {
135138
checks = append(checks, docker.Check{Name: "state ledger", Status: docker.StatusOK, Detail: fmt.Sprintf("schema v%d @ %s", v, ctxName)})
136139
}
137140

141+
// DNS entries for *.localhost (spec 05) — best-effort, only when the current
142+
// dir is a workspace with a configured proxy. Never fatal (opt-in).
143+
if m, err := config.Load(cwd); err == nil && proxy.Enabled(m) {
144+
var hosts []string
145+
for _, r := range proxy.BuildRoutes(m) {
146+
hosts = append(hosts, r.Host)
147+
}
148+
if missing, err := dns.Missing(dns.DefaultHostsPath, hosts); err == nil {
149+
if len(missing) == 0 {
150+
checks = append(checks, docker.Check{Name: "dns (/etc/hosts)", Status: docker.StatusOK, Detail: fmt.Sprintf("%d *.localhost host(s) resolved", len(hosts))})
151+
} else {
152+
checks = append(checks, docker.Check{
153+
Name: "dns (/etc/hosts)", Status: docker.StatusWarn,
154+
Detail: fmt.Sprintf("%d of %d *.localhost host(s) missing", len(missing), len(hosts)),
155+
Remediation: "run `sudo devstack dns setup`",
156+
})
157+
}
158+
}
159+
}
160+
138161
// Local-CA trust (spec 05) — opt-in, so never fatal: report readiness as a
139162
// warning with the exact remediation when not fully set up.
140163
ts := trust.New().Status(ctx)

0 commit comments

Comments
 (0)