2026-04-04 22:24:56 -03:00
|
|
|
package state
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
2026-04-09 04:56:41 -03:00
|
|
|
var quarantineCorruptFileImpl = quarantineCorruptFileDefault
|
|
|
|
|
|
2026-04-09 01:38:06 -03:00
|
|
|
// quarantineCorruptFile runs one orchestration or CLI step.
|
|
|
|
|
// Signature: quarantineCorruptFile(path string, payload []byte, replacement []byte, mode os.FileMode) error.
|
|
|
|
|
// Why: keeps behavior explicit so startup/shutdown workflows remain maintainable as services evolve.
|
2026-04-04 22:24:56 -03:00
|
|
|
func quarantineCorruptFile(path string, payload []byte, replacement []byte, mode os.FileMode) error {
|
2026-04-09 04:56:41 -03:00
|
|
|
return quarantineCorruptFileImpl(path, payload, replacement, mode)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// quarantineCorruptFileDefault runs one orchestration or CLI step.
|
|
|
|
|
// Signature: quarantineCorruptFileDefault(path string, payload []byte, replacement []byte, mode os.FileMode) error.
|
|
|
|
|
// Why: keeps production file-healing behavior as the default while tests can
|
|
|
|
|
// deterministically force heal failures in root/sudo environments.
|
|
|
|
|
func quarantineCorruptFileDefault(path string, payload []byte, replacement []byte, mode os.FileMode) error {
|
2026-04-04 22:24:56 -03:00
|
|
|
if err := os.MkdirAll(filepath.Dir(path), 0o750); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
backup := fmt.Sprintf("%s.corrupt-%s", path, time.Now().UTC().Format("20060102T150405Z"))
|
|
|
|
|
if err := os.WriteFile(backup, payload, 0o600); err != nil {
|
|
|
|
|
return fmt.Errorf("write backup %s: %w", backup, err)
|
|
|
|
|
}
|
|
|
|
|
if err := os.WriteFile(path, replacement, mode); err != nil {
|
|
|
|
|
return fmt.Errorf("write replacement %s: %w", path, err)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|