aboutsummaryrefslogtreecommitdiff
path: root/weed/admin/dash/config_persistence.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/admin/dash/config_persistence.go')
-rw-r--r--weed/admin/dash/config_persistence.go270
1 files changed, 270 insertions, 0 deletions
diff --git a/weed/admin/dash/config_persistence.go b/weed/admin/dash/config_persistence.go
new file mode 100644
index 000000000..93d9f6a09
--- /dev/null
+++ b/weed/admin/dash/config_persistence.go
@@ -0,0 +1,270 @@
+package dash
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "path/filepath"
+ "time"
+
+ "github.com/seaweedfs/seaweedfs/weed/glog"
+)
+
+const (
+ // Configuration file names
+ MaintenanceConfigFile = "maintenance.json"
+ AdminConfigFile = "admin.json"
+ ConfigDirPermissions = 0755
+ ConfigFilePermissions = 0644
+)
+
+// ConfigPersistence handles saving and loading configuration files
+type ConfigPersistence struct {
+ dataDir string
+}
+
+// NewConfigPersistence creates a new configuration persistence manager
+func NewConfigPersistence(dataDir string) *ConfigPersistence {
+ return &ConfigPersistence{
+ dataDir: dataDir,
+ }
+}
+
+// SaveMaintenanceConfig saves maintenance configuration to JSON file
+func (cp *ConfigPersistence) SaveMaintenanceConfig(config *MaintenanceConfig) error {
+ if cp.dataDir == "" {
+ return fmt.Errorf("no data directory specified, cannot save configuration")
+ }
+
+ configPath := filepath.Join(cp.dataDir, MaintenanceConfigFile)
+
+ // Create directory if it doesn't exist
+ if err := os.MkdirAll(cp.dataDir, ConfigDirPermissions); err != nil {
+ return fmt.Errorf("failed to create config directory: %v", err)
+ }
+
+ // Marshal configuration to JSON
+ configData, err := json.MarshalIndent(config, "", " ")
+ if err != nil {
+ return fmt.Errorf("failed to marshal maintenance config: %v", err)
+ }
+
+ // Write to file
+ if err := os.WriteFile(configPath, configData, ConfigFilePermissions); err != nil {
+ return fmt.Errorf("failed to write maintenance config file: %v", err)
+ }
+
+ glog.V(1).Infof("Saved maintenance configuration to %s", configPath)
+ return nil
+}
+
+// LoadMaintenanceConfig loads maintenance configuration from JSON file
+func (cp *ConfigPersistence) LoadMaintenanceConfig() (*MaintenanceConfig, error) {
+ if cp.dataDir == "" {
+ glog.V(1).Infof("No data directory specified, using default maintenance configuration")
+ return DefaultMaintenanceConfig(), nil
+ }
+
+ configPath := filepath.Join(cp.dataDir, MaintenanceConfigFile)
+
+ // Check if file exists
+ if _, err := os.Stat(configPath); os.IsNotExist(err) {
+ glog.V(1).Infof("Maintenance config file does not exist, using defaults: %s", configPath)
+ return DefaultMaintenanceConfig(), nil
+ }
+
+ // Read file
+ configData, err := os.ReadFile(configPath)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read maintenance config file: %v", err)
+ }
+
+ // Unmarshal JSON
+ var config MaintenanceConfig
+ if err := json.Unmarshal(configData, &config); err != nil {
+ return nil, fmt.Errorf("failed to unmarshal maintenance config: %v", err)
+ }
+
+ glog.V(1).Infof("Loaded maintenance configuration from %s", configPath)
+ return &config, nil
+}
+
+// SaveAdminConfig saves general admin configuration to JSON file
+func (cp *ConfigPersistence) SaveAdminConfig(config map[string]interface{}) error {
+ if cp.dataDir == "" {
+ return fmt.Errorf("no data directory specified, cannot save configuration")
+ }
+
+ configPath := filepath.Join(cp.dataDir, AdminConfigFile)
+
+ // Create directory if it doesn't exist
+ if err := os.MkdirAll(cp.dataDir, ConfigDirPermissions); err != nil {
+ return fmt.Errorf("failed to create config directory: %v", err)
+ }
+
+ // Marshal configuration to JSON
+ configData, err := json.MarshalIndent(config, "", " ")
+ if err != nil {
+ return fmt.Errorf("failed to marshal admin config: %v", err)
+ }
+
+ // Write to file
+ if err := os.WriteFile(configPath, configData, ConfigFilePermissions); err != nil {
+ return fmt.Errorf("failed to write admin config file: %v", err)
+ }
+
+ glog.V(1).Infof("Saved admin configuration to %s", configPath)
+ return nil
+}
+
+// LoadAdminConfig loads general admin configuration from JSON file
+func (cp *ConfigPersistence) LoadAdminConfig() (map[string]interface{}, error) {
+ if cp.dataDir == "" {
+ glog.V(1).Infof("No data directory specified, using default admin configuration")
+ return make(map[string]interface{}), nil
+ }
+
+ configPath := filepath.Join(cp.dataDir, AdminConfigFile)
+
+ // Check if file exists
+ if _, err := os.Stat(configPath); os.IsNotExist(err) {
+ glog.V(1).Infof("Admin config file does not exist, using defaults: %s", configPath)
+ return make(map[string]interface{}), nil
+ }
+
+ // Read file
+ configData, err := os.ReadFile(configPath)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read admin config file: %v", err)
+ }
+
+ // Unmarshal JSON
+ var config map[string]interface{}
+ if err := json.Unmarshal(configData, &config); err != nil {
+ return nil, fmt.Errorf("failed to unmarshal admin config: %v", err)
+ }
+
+ glog.V(1).Infof("Loaded admin configuration from %s", configPath)
+ return config, nil
+}
+
+// GetConfigPath returns the path to a configuration file
+func (cp *ConfigPersistence) GetConfigPath(filename string) string {
+ if cp.dataDir == "" {
+ return ""
+ }
+ return filepath.Join(cp.dataDir, filename)
+}
+
+// ListConfigFiles returns all configuration files in the data directory
+func (cp *ConfigPersistence) ListConfigFiles() ([]string, error) {
+ if cp.dataDir == "" {
+ return nil, fmt.Errorf("no data directory specified")
+ }
+
+ files, err := os.ReadDir(cp.dataDir)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read config directory: %v", err)
+ }
+
+ var configFiles []string
+ for _, file := range files {
+ if !file.IsDir() && filepath.Ext(file.Name()) == ".json" {
+ configFiles = append(configFiles, file.Name())
+ }
+ }
+
+ return configFiles, nil
+}
+
+// BackupConfig creates a backup of a configuration file
+func (cp *ConfigPersistence) BackupConfig(filename string) error {
+ if cp.dataDir == "" {
+ return fmt.Errorf("no data directory specified")
+ }
+
+ configPath := filepath.Join(cp.dataDir, filename)
+ if _, err := os.Stat(configPath); os.IsNotExist(err) {
+ return fmt.Errorf("config file does not exist: %s", filename)
+ }
+
+ // Create backup filename with timestamp
+ timestamp := time.Now().Format("2006-01-02_15-04-05")
+ backupName := fmt.Sprintf("%s.backup_%s", filename, timestamp)
+ backupPath := filepath.Join(cp.dataDir, backupName)
+
+ // Copy file
+ configData, err := os.ReadFile(configPath)
+ if err != nil {
+ return fmt.Errorf("failed to read config file: %v", err)
+ }
+
+ if err := os.WriteFile(backupPath, configData, ConfigFilePermissions); err != nil {
+ return fmt.Errorf("failed to create backup: %v", err)
+ }
+
+ glog.V(1).Infof("Created backup of %s as %s", filename, backupName)
+ return nil
+}
+
+// RestoreConfig restores a configuration file from a backup
+func (cp *ConfigPersistence) RestoreConfig(filename, backupName string) error {
+ if cp.dataDir == "" {
+ return fmt.Errorf("no data directory specified")
+ }
+
+ backupPath := filepath.Join(cp.dataDir, backupName)
+ if _, err := os.Stat(backupPath); os.IsNotExist(err) {
+ return fmt.Errorf("backup file does not exist: %s", backupName)
+ }
+
+ // Read backup file
+ backupData, err := os.ReadFile(backupPath)
+ if err != nil {
+ return fmt.Errorf("failed to read backup file: %v", err)
+ }
+
+ // Write to config file
+ configPath := filepath.Join(cp.dataDir, filename)
+ if err := os.WriteFile(configPath, backupData, ConfigFilePermissions); err != nil {
+ return fmt.Errorf("failed to restore config: %v", err)
+ }
+
+ glog.V(1).Infof("Restored %s from backup %s", filename, backupName)
+ return nil
+}
+
+// GetDataDir returns the data directory path
+func (cp *ConfigPersistence) GetDataDir() string {
+ return cp.dataDir
+}
+
+// IsConfigured returns true if a data directory is configured
+func (cp *ConfigPersistence) IsConfigured() bool {
+ return cp.dataDir != ""
+}
+
+// GetConfigInfo returns information about the configuration storage
+func (cp *ConfigPersistence) GetConfigInfo() map[string]interface{} {
+ info := map[string]interface{}{
+ "data_dir_configured": cp.IsConfigured(),
+ "data_dir": cp.dataDir,
+ }
+
+ if cp.IsConfigured() {
+ // Check if data directory exists
+ if _, err := os.Stat(cp.dataDir); err == nil {
+ info["data_dir_exists"] = true
+
+ // List config files
+ configFiles, err := cp.ListConfigFiles()
+ if err == nil {
+ info["config_files"] = configFiles
+ }
+ } else {
+ info["data_dir_exists"] = false
+ }
+ }
+
+ return info
+}