fix: complete target diagnostics and reset inspection
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user