fix: make daemon reset conflict safe
This commit is contained in:
@@ -336,12 +336,30 @@ func (a *Adapter) disable(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("read Docker daemon recovery metadata: %w", err)
|
||||
}
|
||||
|
||||
// daemon.json is a shared, whole-file configuration surface. Restore it only
|
||||
// while the complete current document is exactly the document proxyctl last
|
||||
// applied. This protects both managed proxy keys and unrelated administrator
|
||||
// edits from being overwritten by the original snapshot.
|
||||
current, currentErr := a.files.ReadFile(a.configuration.DaemonConfigPath)
|
||||
if currentErr != nil && !errors.Is(currentErr, fs.ErrNotExist) {
|
||||
return fmt.Errorf("read Docker daemon configuration before restore: %w", currentErr)
|
||||
}
|
||||
alreadyOriginal := metadata.OriginalExists && currentErr == nil && fingerprint(current) == fingerprint(metadata.Original)
|
||||
alreadyAbsent := !metadata.OriginalExists && errors.Is(currentErr, fs.ErrNotExist)
|
||||
if alreadyOriginal || alreadyAbsent {
|
||||
if err := a.files.Remove(a.configuration.RecoveryPath); err != nil && !errors.Is(err, fs.ErrNotExist) {
|
||||
return fmt.Errorf("clean Docker daemon recovery metadata for already-restored configuration: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if currentErr != nil || fingerprint(current) != metadata.ConfigFingerprint {
|
||||
return errors.New("Docker daemon configuration changed after proxyctl applied it; refusing to overwrite current configuration or discard recovery metadata")
|
||||
}
|
||||
|
||||
if metadata.OriginalExists {
|
||||
current, _ := a.files.ReadFile(a.configuration.DaemonConfigPath)
|
||||
if fingerprint(current) != fingerprint(metadata.Original) {
|
||||
if err := a.files.AtomicWrite(a.configuration.DaemonConfigPath, metadata.Original, os.FileMode(metadata.OriginalMode)); err != nil {
|
||||
return fmt.Errorf("restore Docker daemon configuration: %w", err)
|
||||
}
|
||||
if err := a.files.AtomicWrite(a.configuration.DaemonConfigPath, metadata.Original, os.FileMode(metadata.OriginalMode)); err != nil {
|
||||
return fmt.Errorf("restore Docker daemon configuration: %w", err)
|
||||
}
|
||||
} else if err := a.files.Remove(a.configuration.DaemonConfigPath); err != nil && !errors.Is(err, fs.ErrNotExist) {
|
||||
return fmt.Errorf("remove managed Docker daemon configuration: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user