Add resiliency primitives: atomic writes, reconcile mutex, state backup
- Add storage.WriteFileAtomic (temp + rename) and storage.CopyFile helpers - Convert all 8 production config writers to atomic writes: config/state.yaml, dnsmasq, nftables, domains, wireguard (config + secrets + peers + wg0.conf), tunnel/cloudflared - Add sync.Mutex to Reconciler to serialize concurrent Reconcile() calls triggered by domain registration goroutines - Add state.yaml backup (.bak) before every write; LoadState falls back to backup if primary is corrupted - Reconciler refuses to use empty config on corruption (only on first run when no state file exists yet)
This commit is contained in:
@@ -6,6 +6,8 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/wild-cloud/wild-central/internal/storage"
|
||||
)
|
||||
|
||||
const defaultRulesPath = "/etc/nftables.d/wild-cloud.nft"
|
||||
@@ -144,7 +146,7 @@ func (m *Manager) WriteRules(content string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.WriteFile(m.rulesPath, []byte(content), 0644); err != nil {
|
||||
if err := storage.WriteFileAtomic(m.rulesPath, []byte(content), 0644); err != nil {
|
||||
return fmt.Errorf("writing rules file: %w", err)
|
||||
}
|
||||
|
||||
@@ -171,7 +173,7 @@ func (m *Manager) WriteDisabledRules() error {
|
||||
"# Managed by Wild Cloud Central API — do not edit manually\n\n" +
|
||||
"table inet wild-cloud {}\n" +
|
||||
"delete table inet wild-cloud\n"
|
||||
if err := os.WriteFile(m.rulesPath, []byte(content), 0644); err != nil {
|
||||
if err := storage.WriteFileAtomic(m.rulesPath, []byte(content), 0644); err != nil {
|
||||
return fmt.Errorf("writing disabled rules file: %w", err)
|
||||
}
|
||||
slog.Info("nftables rules disabled", "component", "nftables", "path", m.rulesPath)
|
||||
|
||||
Reference in New Issue
Block a user