94 lines
2.0 KiB
Go
94 lines
2.0 KiB
Go
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
)
|
|
|
|
var (
|
|
mu sync.RWMutex
|
|
cfg *AppConfig
|
|
cfgPath string
|
|
)
|
|
|
|
func init() {
|
|
cfgPath = resolveCfgPath()
|
|
hostname, _ := os.Hostname()
|
|
cfg = &AppConfig{
|
|
Node: NodeInfo{
|
|
Hostname: hostname,
|
|
UpdateHistory: []UpdateRecord{},
|
|
Backup: BackupConfig{
|
|
Targets: []BackupTarget{},
|
|
History: []BackupExecution{},
|
|
},
|
|
},
|
|
Nodes: []RemoteNode{},
|
|
Services: []Service{},
|
|
}
|
|
if data, err := os.ReadFile(cfgPath); err == nil {
|
|
_ = json.Unmarshal(data, cfg)
|
|
}
|
|
ensureSlices()
|
|
}
|
|
|
|
func ensureSlices() {
|
|
if cfg.Node.UpdateHistory == nil {
|
|
cfg.Node.UpdateHistory = []UpdateRecord{}
|
|
}
|
|
if cfg.Node.Backup.Targets == nil {
|
|
cfg.Node.Backup.Targets = []BackupTarget{}
|
|
}
|
|
if cfg.Node.Backup.History == nil {
|
|
cfg.Node.Backup.History = []BackupExecution{}
|
|
}
|
|
if cfg.Nodes == nil {
|
|
cfg.Nodes = []RemoteNode{}
|
|
}
|
|
if cfg.Services == nil {
|
|
cfg.Services = []Service{}
|
|
}
|
|
}
|
|
|
|
func resolveCfgPath() string {
|
|
const etcPath = "/etc/nodemaster/nodemaster.conf"
|
|
if err := os.MkdirAll(filepath.Dir(etcPath), 0755); err == nil {
|
|
if f, err := os.OpenFile(etcPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600); err == nil {
|
|
f.Close()
|
|
return etcPath
|
|
}
|
|
}
|
|
home, err := os.UserHomeDir()
|
|
if err != nil {
|
|
home = "."
|
|
}
|
|
return filepath.Join(home, ".nodemaster.conf")
|
|
}
|
|
|
|
func persist() error {
|
|
data, err := json.MarshalIndent(cfg, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := os.MkdirAll(filepath.Dir(cfgPath), 0755); err != nil {
|
|
return fmt.Errorf("mkdir: %w", err)
|
|
}
|
|
// 0600: the config now embeds the restic repository password, so it must
|
|
// not be group/world-readable. Chmod covers pre-existing files that were
|
|
// created before this field existed (WriteFile's mode only applies on
|
|
// create, not to files that already exist with looser permissions).
|
|
if err := os.WriteFile(cfgPath, data, 0600); err != nil {
|
|
return err
|
|
}
|
|
_ = os.Chmod(cfgPath, 0600)
|
|
return nil
|
|
}
|
|
|
|
// ConfigPath returns the resolved config file path.
|
|
func ConfigPath() string {
|
|
return cfgPath
|
|
}
|