func main() { // Most flags are defined in the confd/config package which allows us to // override configuration settings from the command line. Parse the flags now // to make them active. flag.Parse() if printVersion { fmt.Printf("confd %s\n", Version) os.Exit(0) } if configFile == "" { if IsFileExist(defaultConfigFile) { configFile = defaultConfigFile } } // Initialize the global configuration. log.Debug("Loading confd configuration") if err := config.LoadConfig(configFile); err != nil { log.Fatal(err.Error()) } // Configure logging. While you can enable debug and verbose logging, however // if quiet is set to true then debug and verbose messages will not be printed. log.SetQuiet(config.Quiet()) log.SetVerbose(config.Verbose()) log.SetDebug(config.Debug()) log.Notice("Starting confd") // Create the storage client log.Notice("Backend set to " + config.Backend()) store, err := backends.New(config.Backend()) if err != nil { log.Fatal(err.Error()) } signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) for { runErrors := template.ProcessTemplateResources(store) // If the -onetime flag is passed on the command line we immediately exit // after processing the template config files. if onetime { if len(runErrors) > 0 { os.Exit(1) } os.Exit(0) } select { case c := <-signalChan: log.Info(fmt.Sprintf("captured %v exiting...", c)) os.Exit(0) case <-time.After(time.Duration(config.Interval()) * time.Second): // Continue processing templates. } } }
func main() { // Most flags are defined in the confd/config package which allows us to // override configuration settings from the command line. Parse the flags now // to make them active. flag.Parse() if configFile == "" { if IsFileExist(defaultConfigFile) { configFile = defaultConfigFile } } // Initialize the global configuration. log.Debug("Loading confd configuration") if err := config.LoadConfig(configFile); err != nil { log.Fatal(err.Error()) } // Configure logging. While you can enable debug and verbose logging, however // if quiet is set to true then debug and verbose messages will not be printed. log.SetQuiet(config.Quiet()) log.SetVerbose(config.Verbose()) log.SetDebug(config.Debug()) log.Notice("Starting confd") // Create the etcd client upfront and use it for the life of the process. // The etcdClient is an http.Client and designed to be reused. log.Notice("etcd nodes set to " + strings.Join(config.EtcdNodes(), ", ")) etcdClient, err := etcdutil.NewEtcdClient(config.EtcdNodes(), config.ClientCert(), config.ClientKey(), config.ClientCaKeys()) if err != nil { log.Fatal(err.Error()) } for { runErrors := template.ProcessTemplateResources(etcdClient) // If the -onetime flag is passed on the command line we immediately exit // after processing the template config files. if onetime { if len(runErrors) > 0 { os.Exit(1) } os.Exit(0) } time.Sleep(time.Duration(config.Interval()) * time.Second) } }
func main() { // Most flags are defined in the confd/config package which allows us to // override configuration settings from the command line. Parse the flags now // to make them active. flag.Parse() if configFile == "" { if IsFileExist(defaultConfigFile) { configFile = defaultConfigFile } } // Initialize the global configuration. log.Debug("Loading confd configuration") if err := config.LoadConfig(configFile); err != nil { log.Fatal(err.Error()) } // Configure logging. While you can enable debug and verbose logging, however // if quiet is set to true then debug and verbose messages will not be printed. log.SetQuiet(config.Quiet()) log.SetVerbose(config.Verbose()) log.SetDebug(config.Debug()) log.Notice("Starting confd") // Create the storage client store, err := createStoreClient(config.Backend()) if err != nil { log.Fatal(err.Error()) } for { runErrors := template.ProcessTemplateResources(store) // If the -onetime flag is passed on the command line we immediately exit // after processing the template config files. if onetime { if len(runErrors) > 0 { os.Exit(1) } os.Exit(0) } time.Sleep(time.Duration(config.Interval()) * time.Second) } }
// initConfig initializes the confd configuration by first setting defaults, // then overriding setting from the confd config file, and finally overriding // settings from flags set on the command line. // It returns an error if any. func initConfig() error { if configFile == "" { if _, err := os.Stat(defaultConfigFile); !os.IsNotExist(err) { configFile = defaultConfigFile } } // Set defaults. config = Config{ Backend: "etcd", ConfDir: "/etc/confd", Interval: 600, Prefix: "/", Scheme: "http", } // Update config from the TOML configuration file. if configFile == "" { log.Warning("Skipping confd config file.") } else { log.Debug("Loading " + configFile) configBytes, err := ioutil.ReadFile(configFile) if err != nil { return err } _, err = toml.Decode(string(configBytes), &config) if err != nil { return err } } // Update config from commandline flags. processFlags() // Configure logging. log.SetQuiet(config.Quiet) log.SetVerbose(config.Verbose) log.SetDebug(config.Debug) // Update BackendNodes from SRV records. if config.Backend != "env" && config.SRVDomain != "" { log.Info("SRV domain set to " + config.SRVDomain) srvNodes, err := getBackendNodesFromSRV(config.Backend, config.SRVDomain, config.Scheme) if err != nil { return errors.New("Cannot get nodes from SRV records " + err.Error()) } config.BackendNodes = srvNodes } if len(config.BackendNodes) == 0 { switch config.Backend { case "consul": config.BackendNodes = []string{"127.0.0.1:8500"} case "etcd": peerstr := os.Getenv("ETCDCTL_PEERS") if len(peerstr) > 0 { config.BackendNodes = strings.Split(peerstr, ",") } else { config.BackendNodes = []string{"http://127.0.0.1:4001"} } case "redis": config.BackendNodes = []string{"127.0.0.1:6379"} } } // Initialize the storage client log.Notice("Backend set to " + config.Backend) if config.Watch { unsupportedBackends := map[string]bool{ "zookeeper": true, "redis": true, } if unsupportedBackends[config.Backend] { log.Notice(fmt.Sprintf("Watch is not supported for backend %s. Exiting...", config.Backend)) os.Exit(1) } } backendsConfig = backends.Config{ Backend: config.Backend, ClientCaKeys: config.ClientCaKeys, ClientCert: config.ClientCert, ClientKey: config.ClientKey, BackendNodes: config.BackendNodes, Scheme: config.Scheme, } // Template configuration. templateConfig = template.Config{ ConfDir: config.ConfDir, ConfigDir: filepath.Join(config.ConfDir, "conf.d"), KeepStageFile: keepStageFile, Noop: config.Noop, Prefix: config.Prefix, TemplateDir: filepath.Join(config.ConfDir, "templates"), } return nil }