diff --git a/app.go b/app.go index 13c71a3a..2ad14472 100644 --- a/app.go +++ b/app.go @@ -93,16 +93,17 @@ func run(args options) { os.Exit(0) }() - // Do the upgrade if necessary - err := upgradeConfig() - if err != nil { - log.Fatal(err) - } + if !config.firstRun { + // Do the upgrade if necessary + err := upgradeConfig() + if err != nil { + log.Fatal(err) + } - // parse from config file - err = parseConfig() - if err != nil { - log.Fatal(err) + err = parseConfig() + if err != nil { + os.Exit(1) + } } if (runtime.GOOS == "linux" || runtime.GOOS == "darwin") && @@ -120,10 +121,12 @@ func run(args options) { loadFilters() - // Save the updated config - err = config.write() - if err != nil { - log.Fatal(err) + if !config.firstRun { + // Save the updated config + err := config.write() + if err != nil { + log.Fatal(err) + } } // Init the DNS server instance before registering HTTP handlers @@ -131,7 +134,7 @@ func run(args options) { initDNSServer(dnsBaseDir) if !config.firstRun { - err = startDNSServer() + err := startDNSServer() if err != nil { log.Fatal(err) } diff --git a/config.go b/config.go index 24ee8605..c0319698 100644 --- a/config.go +++ b/config.go @@ -30,6 +30,10 @@ type logSettings struct { // configuration is loaded from YAML // field ordering is important -- yaml fields will mirror ordering from here type configuration struct { + // Raw file data to avoid re-reading of configuration file + // It's reset after config is parsed + fileData []byte + ourConfigFilename string // Config filename (can be overridden via the command line arguments) ourWorkingDir string // Location of our directory, used to protect against CWD being somewhere else firstRun bool // if set to true, don't run any services except HTTP web inteface, and serve only first-run html @@ -174,7 +178,7 @@ func (c *configuration) getConfigFilename() string { func getLogSettings() logSettings { l := logSettings{} yamlFile, err := readConfigFile() - if err != nil || yamlFile == nil { + if err != nil { return l } err = yaml.Unmarshal(yamlFile, &l) @@ -190,13 +194,9 @@ func parseConfig() error { log.Debug("Reading config file: %s", configFile) yamlFile, err := readConfigFile() if err != nil { - log.Error("Couldn't read config file: %s", err) return err } - if yamlFile == nil { - log.Error("YAML file doesn't exist, skipping it") - return nil - } + config.fileData = nil err = yaml.Unmarshal(yamlFile, &config) if err != nil { log.Error("Couldn't parse config file: %s", err) @@ -213,22 +213,23 @@ func parseConfig() error { // readConfigFile reads config file contents if it exists func readConfigFile() ([]byte, error) { - configFile := config.getConfigFilename() - if _, err := os.Stat(configFile); os.IsNotExist(err) { - // do nothing, file doesn't exist - return nil, nil + if len(config.fileData) != 0 { + return config.fileData, nil } - return ioutil.ReadFile(configFile) + + configFile := config.getConfigFilename() + d, err := ioutil.ReadFile(configFile) + if err != nil { + log.Error("Couldn't read config file %s: %s", configFile, err) + return nil, err + } + return d, nil } // Saves configuration to the YAML file and also saves the user filter contents to a file func (c *configuration) write() error { c.Lock() defer c.Unlock() - if config.firstRun { - log.Debug("Silently refusing to write config because first run and not configured yet") - return nil - } configFile := config.getConfigFilename() log.Debug("Writing YAML file: %s", configFile) yamlText, err := yaml.Marshal(&config) diff --git a/upgrade.go b/upgrade.go index e730d34b..c2de9f68 100644 --- a/upgrade.go +++ b/upgrade.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -16,21 +15,15 @@ const currentSchemaVersion = 3 // used for upgrading from old configs to new con // Performs necessary upgrade operations if needed func upgradeConfig() error { // read a config file into an interface map, so we can manipulate values without losing any - configFile := config.getConfigFilename() - if _, err := os.Stat(configFile); os.IsNotExist(err) { - log.Printf("config file %s does not exist, nothing to upgrade", configFile) - return nil - } diskConfig := map[string]interface{}{} - body, err := ioutil.ReadFile(configFile) + body, err := readConfigFile() if err != nil { - log.Printf("Couldn't read config file '%s': %s", configFile, err) return err } err = yaml.Unmarshal(body, &diskConfig) if err != nil { - log.Printf("Couldn't parse config file '%s': %s", configFile, err) + log.Printf("Couldn't parse config file: %s", err) return err } @@ -87,6 +80,7 @@ func upgradeConfigSchema(oldVersion int, diskConfig *map[string]interface{}) err return err } + config.fileData = body err = file.SafeWrite(configFile, body) if err != nil { log.Printf("Couldn't save YAML config: %s", err)