package bacula import ( "fmt" "os" "os/exec" "strings" "github.com/bams/backend/internal/config" "github.com/bams/backend/internal/logger" ) type Status struct { Status string `json:"status"` // "running", "stopped", "unknown" PID int `json:"pid,omitempty"` Version string `json:"version,omitempty"` LastError string `json:"last_error,omitempty"` } type Service struct { config *config.Config logger *logger.Logger } func NewService(cfg *config.Config, log *logger.Logger) *Service { return &Service{ config: cfg, logger: log, } } func (s *Service) GetStatus() (*Status, error) { s.logger.Debug("Getting Bacula SD status") status := &Status{ Status: "unknown", } // Check if bacula-sd process is running cmd := exec.Command("systemctl", "is-active", "bacula-sd") output, err := cmd.CombinedOutput() if err == nil { if strings.TrimSpace(string(output)) == "active" { status.Status = "running" } else { status.Status = "stopped" } } return status, nil } func (s *Service) GetConfig() (string, error) { s.logger.Debug("Getting Bacula SD config") if _, err := os.Stat(s.config.BaculaConfig); err != nil { return "", fmt.Errorf("config file not found: %w", err) } data, err := os.ReadFile(s.config.BaculaConfig) if err != nil { return "", fmt.Errorf("failed to read config: %w", err) } return string(data), nil } func (s *Service) GenerateConfig() (string, error) { s.logger.Info("Generating Bacula SD config") // Generate template configuration config := `# Bacula Storage Daemon Configuration # Generated by BAMS Storage { Name = bacula-sd WorkingDirectory = /var/lib/bacula PidDirectory = /run/bacula Maximum Concurrent Jobs = 20 SDAddress = 0.0.0.0 } Director { Name = bacula-dir Password = "changeme" } Device { Name = FileStorage Media Type = File Archive Device = /var/lib/bacula/storage LabelMedia = yes Random Access = yes AutomaticMount = yes RemovableMedia = no AlwaysOpen = no } # Autochanger configuration will be added here ` return config, nil } func (s *Service) RunInventory() error { s.logger.Info("Running Bacula inventory") // Use bconsole to run inventory cmd := exec.Command("bconsole", "-c", "update slots") output, err := cmd.CombinedOutput() if err != nil { s.logger.Error("Failed to run inventory", "error", string(output)) return fmt.Errorf("inventory failed: %w", err) } return nil } func (s *Service) Restart() error { s.logger.Info("Restarting Bacula SD") cmd := exec.Command("systemctl", "restart", "bacula-sd") output, err := cmd.CombinedOutput() if err != nil { s.logger.Error("Failed to restart Bacula SD", "error", string(output)) return fmt.Errorf("restart failed: %w", err) } return nil }