fix: finish progressive Target detection

This commit is contained in:
proxyctl coordinator
2026-07-17 21:25:43 +08:00
parent ad651402fd
commit 8348fa3ac8
17 changed files with 672 additions and 221 deletions
+32 -18
View File
@@ -348,15 +348,18 @@ func (a *Adapter) DiagnosticChecks(ctx context.Context, _ *profile.Profile) []ta
}
func (a *Adapter) Availability(ctx context.Context) target.Availability {
availability, _ := a.detectAvailability(ctx)
availability, _, _ := a.detectAvailability(ctx)
return availability
}
func (a *Adapter) detectAvailability(ctx context.Context) (target.Availability, error) {
// detectAvailability returns the settings observation that established
// availability so Detect can inspect that exact observation without issuing a
// second twelve-command gsettings probe.
func (a *Adapter) detectAvailability(ctx context.Context) (target.Availability, settings, error) {
output, err := a.run(ctx, "list-schemas")
if err != nil {
safeErr := redact(err)
return target.Availability{Evidence: fmt.Sprintf("GNOME Target requires a usable %s command: %v", a.configuration.CommandName, safeErr)}, safeErr
return target.Availability{Evidence: fmt.Sprintf("GNOME Target requires a usable %s command: %v", a.configuration.CommandName, safeErr)}, settings{}, safeErr
}
present := make(map[string]bool)
for _, schema := range strings.Fields(output) {
@@ -364,49 +367,60 @@ func (a *Adapter) detectAvailability(ctx context.Context) (target.Availability,
}
for _, schema := range requiredSchemas {
if !present[schema] {
return target.Availability{Evidence: "required GNOME settings schema is unavailable: " + schema}, nil
return target.Availability{Evidence: "required GNOME settings schema is unavailable: " + schema}, settings{}, nil
}
}
if _, err := a.readSettings(ctx); err != nil {
current, err := a.readSettings(ctx)
if err != nil {
safeErr := redact(err)
return target.Availability{Evidence: fmt.Sprintf("GNOME proxy schema is present but unusable for the desktop session: %v", safeErr)}, safeErr
return target.Availability{Evidence: fmt.Sprintf("GNOME proxy schema is present but unusable for the desktop session: %v", safeErr)}, settings{}, safeErr
}
return target.Availability{Available: true, Evidence: "gsettings command and GNOME proxy schemas are usable for the owning user"}, nil
return target.Availability{Available: true, Evidence: "gsettings command and GNOME proxy schemas are usable for the owning user"}, current, nil
}
func (a *Adapter) Detect(ctx context.Context, active *profile.Profile) target.Detection {
availability, err := a.detectAvailability(ctx)
return target.Detection{Availability: availability, Inspection: a.Inspect(ctx, active), Err: err}
availability, current, availabilityErr := a.detectAvailability(ctx)
if !availability.Available && availabilityErr == nil {
return target.Detection{Availability: availability}
}
inspection, inspectionErr := a.inspectSettings(active, current, availabilityErr)
return target.Detection{Availability: availability, Inspection: inspection, Err: errors.Join(availabilityErr, inspectionErr)}
}
func (a *Adapter) Inspect(ctx context.Context, active *profile.Profile) target.Inspection {
metadata, managed, metadataErr := a.readRecovery()
current, settingsErr := a.readSettings(ctx)
inspection, _ := a.inspectSettings(active, current, settingsErr)
return inspection
}
func (a *Adapter) inspectSettings(active *profile.Profile, current settings, settingsErr error) (target.Inspection, error) {
metadata, managed, metadataErr := a.readRecovery()
if managed || (metadataErr != nil && !errors.Is(metadataErr, fs.ErrNotExist)) {
if metadataErr != nil {
return target.Inspection{State: target.Drifted, Evidence: "managed GNOME recovery metadata cannot be read"}
return target.Inspection{State: target.Drifted, Evidence: "managed GNOME recovery metadata cannot be read"}, redact(metadataErr)
}
if settingsErr != nil {
return target.Inspection{State: target.Drifted, Evidence: "managed GNOME settings cannot be read: " + redact(settingsErr).Error()}
return target.Inspection{State: target.Drifted, Evidence: "managed GNOME settings cannot be read: " + redact(settingsErr).Error()}, redact(settingsErr)
}
if fingerprint(current) == metadata.LastFingerprint && active != nil {
desired, err := translate(*active)
if err == nil && fingerprint(desired) == metadata.LastFingerprint {
return target.Inspection{State: target.Enabled, Evidence: "managed GNOME settings match the Active Profile"}
return target.Inspection{State: target.Enabled, Evidence: "managed GNOME settings match the Active Profile"}, nil
}
}
return target.Inspection{State: target.Drifted, Evidence: "managed GNOME settings do not match the Active Profile"}
return target.Inspection{State: target.Drifted, Evidence: "managed GNOME settings do not match the Active Profile"}, nil
}
if settingsErr != nil {
return target.Inspection{State: target.Disabled, Evidence: "GNOME settings could not be inspected: " + redact(settingsErr).Error()}
safeErr := redact(settingsErr)
return target.Inspection{State: target.Disabled, Evidence: "GNOME settings could not be inspected: " + safeErr.Error()}, safeErr
}
switch current.Mode {
case "manual":
return target.Inspection{State: target.External, Evidence: "recognized external GNOME manual proxy mode is configured"}
return target.Inspection{State: target.External, Evidence: "recognized external GNOME manual proxy mode is configured"}, nil
case "auto":
return target.Inspection{State: target.External, Evidence: "recognized external GNOME automatic proxy mode is configured"}
return target.Inspection{State: target.External, Evidence: "recognized external GNOME automatic proxy mode is configured"}, nil
default:
return target.Inspection{State: target.Disabled, Evidence: "GNOME proxy mode is none; no recognized desktop proxy configuration detected"}
return target.Inspection{State: target.Disabled, Evidence: "GNOME proxy mode is none; no recognized desktop proxy configuration detected"}, nil
}
}