fix: complete target diagnostics and reset inspection

This commit is contained in:
proxyctl coordinator
2026-07-17 10:29:41 +08:00
parent f6c6ead325
commit 0fbaa71e37
14 changed files with 366 additions and 10 deletions
+38
View File
@@ -74,6 +74,8 @@ type Adapter struct {
runner CommandRunner
}
var _ target.Diagnosable = (*Adapter)(nil)
func New(configuration Configuration, files FileSystem, runner CommandRunner) *Adapter {
if configuration.DaemonConfigPath == "" {
configuration.DaemonConfigPath = "/etc/docker/daemon.json"
@@ -102,6 +104,42 @@ func (a *Adapter) Description() target.Description {
func (a *Adapter) Confirmation(bool) string {
return "Docker will restart immediately. This may disrupt running containers and other work. Confirm before proxyctl changes daemon configuration."
}
// DiagnosticChecks performs only systemctl show and filesystem reads/metadata
// probes; service reload/restart and all configuration mutations are excluded.
func (a *Adapter) DiagnosticChecks(ctx context.Context, _ *profile.Profile) []target.Check {
commandCheck := target.Check{Name: "required command and service", OK: true, Evidence: "systemctl can inspect the loaded docker.service"}
if availability, err := a.detect(ctx); err != nil || !availability.Available {
commandCheck.OK = false
if err != nil {
commandCheck.Evidence = profile.RedactText("systemctl show failed: " + err.Error())
} else {
commandCheck.Evidence = availability.Evidence
}
}
schemaCheck := target.Check{Name: "configuration schema", OK: true, Evidence: "Docker daemon configuration and recovery metadata are absent or valid JSON"}
if data, err := a.files.ReadFile(a.configuration.DaemonConfigPath); err == nil {
if _, schemaErr := mergeConfig(data, profile.Profile{}); schemaErr != nil {
schemaCheck.OK = false
schemaCheck.Evidence = profile.RedactText("Docker daemon configuration cannot be safely merged: " + schemaErr.Error())
}
} else if !errors.Is(err, fs.ErrNotExist) {
schemaCheck.OK = false
schemaCheck.Evidence = profile.RedactText("Docker daemon configuration cannot be read: " + err.Error())
}
if schemaCheck.OK {
if _, _, err := a.readRecovery(); err != nil && !errors.Is(err, fs.ErrNotExist) {
schemaCheck.OK = false
schemaCheck.Evidence = profile.RedactText("Docker daemon recovery metadata is invalid or unreadable: " + err.Error())
}
}
return []target.Check{
commandCheck,
schemaCheck,
target.ReadOnlyWriteAuthority(a.configuration.DaemonConfigPath, a.configuration.RecoveryPath),
}
}
func (a *Adapter) Availability(ctx context.Context) target.Availability {
availability, _ := a.detect(ctx)
return availability
@@ -102,6 +102,30 @@ func (f *faultFS) AtomicWrite(path string, data []byte, mode os.FileMode) error
return f.recordingFS.AtomicWrite(path, data, mode)
}
func TestDiagnosticChecksCoverSystemdSchemaAndAuthorityWithoutMutation(t *testing.T) {
a, record, daemonPath, recoveryPath, _ := fixture(t)
checks := a.DiagnosticChecks(context.Background(), activeProfile())
for _, name := range []string{"required command and service", "configuration schema", "write authority"} {
found := false
for _, check := range checks {
found = found || check.Name == name
}
if !found {
t.Errorf("diagnostics missing %q: %#v", name, checks)
}
}
for _, event := range record.events {
if strings.HasPrefix(event, "write ") || strings.HasPrefix(event, "remove ") || strings.Contains(event, " restart ") || strings.Contains(event, "daemon-reload") {
t.Fatalf("diagnostics mutated daemon state: %#v", record.events)
}
}
for _, path := range []string{daemonPath, recoveryPath} {
if _, err := os.Stat(path); !errors.Is(err, os.ErrNotExist) {
t.Fatalf("diagnostics created %s: %v", path, err)
}
}
}
func TestDockerDaemonRunsReusableTargetContract(t *testing.T) {
targettest.Run(t, func(t *testing.T) targettest.Fixture {
a, _, daemonPath, _, _ := fixture(t)