fix: serialize Docker client recovery mutations

This commit is contained in:
proxyctl coordinator
2026-07-17 03:41:03 +08:00
parent 692a715248
commit 4c7a9c36e8
3 changed files with 209 additions and 12 deletions
+27 -10
View File
@@ -104,6 +104,7 @@ type FileSystem interface {
ReadFile(string) ([]byte, error)
AtomicWrite(string, []byte, os.FileMode, *Ownership) error
Remove(string) error
WithLock(string, *Ownership, func() error) error
}
type OSFileSystem struct{ TrustedRoots []string }
@@ -132,6 +133,9 @@ func (f OSFileSystem) Remove(path string) error { return f.store(pat
func (f OSFileSystem) AtomicWrite(path string, data []byte, mode os.FileMode, owner *Ownership) error {
return f.store(path, owner).AtomicWrite(path, data, mode)
}
func (f OSFileSystem) WithLock(path string, owner *Ownership, action func() error) error {
return f.store(path, owner).WithLock(path, action)
}
type priorValue struct {
Present bool `json:"present"`
@@ -191,6 +195,7 @@ func (a *Adapter) usablePath(path string) bool {
}
func (a *Adapter) ConfigPath() string { return a.configuration.ConfigFile }
func (a *Adapter) RecoveryPath() string { return a.configuration.RecoveryFile }
func (a *Adapter) LockPath() string { return a.configuration.RecoveryFile + ".lock" }
func (a *Adapter) Inspect(_ context.Context, active *profile.Profile) target.Inspection {
metadata, managed, metadataErr := a.readRecovery()
@@ -221,17 +226,29 @@ func (a *Adapter) SetDesired(ctx context.Context, enabled bool, active *profile.
if enabled && active == nil {
return target.OperationResult{Inspection: a.Inspect(ctx, active), Err: errors.New("no Active Profile; open Profile management to create and activate one")}
}
if enabled && a.Inspect(ctx, active).State == target.Enabled {
return target.OperationResult{Inspection: a.Inspect(ctx, active)}
}
var err error
if enabled {
err = a.enable(active)
} else {
err = a.disable()
}
inspection := a.Inspect(ctx, active)
var inspection target.Inspection
err := a.files.WithLock(a.LockPath(), a.ownership(), func() error {
if enabled {
inspection = a.Inspect(ctx, active)
if inspection.State == target.Enabled {
return nil
}
if err := a.enable(active); err != nil {
inspection = a.Inspect(ctx, active)
return err
}
} else if err := a.disable(); err != nil {
inspection = a.Inspect(ctx, active)
return err
}
inspection = a.Inspect(ctx, active)
return nil
})
if err != nil {
if inspection.Evidence == "" {
inspection = a.Inspect(ctx, active)
}
err = redactError(err, active)
}
return target.OperationResult{Inspection: inspection, Err: err}