config.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package config
  2. import (
  3. "fmt"
  4. "os"
  5. "github.com/BurntSushi/toml"
  6. "github.com/spf13/cobra"
  7. )
  8. // Config holds all configuration values
  9. type Config struct {
  10. Hostname string `toml:"hostname"`
  11. MQTTHost string `toml:"mqtt_host"`
  12. MQTTPort int `toml:"mqtt_port"`
  13. MQTTUsername string `toml:"mqtt_username"`
  14. MQTTPassword string `toml:"mqtt_password"`
  15. MQTTLWTEnable bool `toml:"mqtt_lwt_enable"`
  16. MQTTRetain bool `toml:"mqtt_retain"`
  17. PollingPeriod int `toml:"polling_period"`
  18. }
  19. // DefaultConfig returns a config with default values
  20. func DefaultConfig() *Config {
  21. return &Config{
  22. Hostname: "",
  23. MQTTHost: "localhost",
  24. MQTTPort: 1883,
  25. MQTTUsername: "",
  26. MQTTPassword: "",
  27. MQTTLWTEnable: true,
  28. MQTTRetain: true,
  29. PollingPeriod: 30,
  30. }
  31. }
  32. // LoadConfigFromFile loads configuration from TOML file
  33. func LoadConfigFromFile(filename string) (*Config, error) {
  34. config := DefaultConfig()
  35. // Check if file exists
  36. if _, err := os.Stat(filename); os.IsNotExist(err) {
  37. // File doesn't exist, return default config
  38. return config, nil
  39. }
  40. // Read and parse TOML file
  41. if _, err := toml.DecodeFile(filename, config); err != nil {
  42. return nil, fmt.Errorf("failed to parse config file %s: %v", filename, err)
  43. }
  44. return config, nil
  45. }
  46. // LoadConfig loads configuration from file first, then overrides with command line flags
  47. func LoadConfig(cmd *cobra.Command) (*Config, error) {
  48. // First load from config file
  49. configFile := "/etc/nvml-gpu-ha.conf"
  50. // Allow override of config file path via flag
  51. if cmd.Flags().Changed("config") {
  52. var err error
  53. configFile, err = cmd.Flags().GetString("config")
  54. if err != nil {
  55. return nil, err
  56. }
  57. }
  58. config, err := LoadConfigFromFile(configFile)
  59. if err != nil {
  60. return nil, err
  61. }
  62. // Override with command line flags if they were explicitly set
  63. if cmd.Flags().Changed("hostname") {
  64. config.Hostname, err = cmd.Flags().GetString("hostname")
  65. if err != nil {
  66. return nil, err
  67. }
  68. }
  69. if cmd.Flags().Changed("mqtt-host") {
  70. config.MQTTHost, err = cmd.Flags().GetString("mqtt-host")
  71. if err != nil {
  72. return nil, err
  73. }
  74. }
  75. if cmd.Flags().Changed("mqtt-port") {
  76. config.MQTTPort, err = cmd.Flags().GetInt("mqtt-port")
  77. if err != nil {
  78. return nil, err
  79. }
  80. }
  81. if cmd.Flags().Changed("mqtt-username") {
  82. config.MQTTUsername, err = cmd.Flags().GetString("mqtt-username")
  83. if err != nil {
  84. return nil, err
  85. }
  86. }
  87. if cmd.Flags().Changed("mqtt-password") {
  88. config.MQTTPassword, err = cmd.Flags().GetString("mqtt-password")
  89. if err != nil {
  90. return nil, err
  91. }
  92. }
  93. if cmd.Flags().Changed("mqtt-lwt-enable") {
  94. config.MQTTLWTEnable, err = cmd.Flags().GetBool("mqtt-lwt-enable")
  95. if err != nil {
  96. return nil, err
  97. }
  98. }
  99. if cmd.Flags().Changed("mqtt-retain") {
  100. config.MQTTRetain, err = cmd.Flags().GetBool("mqtt-retain")
  101. if err != nil {
  102. return nil, err
  103. }
  104. }
  105. if cmd.Flags().Changed("polling-period") {
  106. config.PollingPeriod, err = cmd.Flags().GetInt("polling-period")
  107. if err != nil {
  108. return nil, err
  109. }
  110. }
  111. return config, nil
  112. }
  113. // SaveToFile saves current configuration to a TOML file
  114. func (c *Config) SaveToFile(filename string) error {
  115. file, err := os.Create(filename)
  116. if err != nil {
  117. return fmt.Errorf("failed to create config file %s: %v", filename, err)
  118. }
  119. defer file.Close()
  120. encoder := toml.NewEncoder(file)
  121. if err := encoder.Encode(c); err != nil {
  122. return fmt.Errorf("failed to encode config to file %s: %v", filename, err)
  123. }
  124. return nil
  125. }