diff options
Diffstat (limited to 'weed/admin/dash/config_persistence.go')
| -rw-r--r-- | weed/admin/dash/config_persistence.go | 270 |
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 +} |
