diff --git a/cmd/config-migrate.go b/cmd/config-migrate.go index 04aa35320..063d19ac6 100644 --- a/cmd/config-migrate.go +++ b/cmd/config-migrate.go @@ -88,33 +88,34 @@ func migrateConfig() error { // Version '1' is not supported anymore and deprecated, safe to delete. func purgeV1() error { - cv1, err := loadConfigV1() - if err != nil { - if os.IsNotExist(err) { - return nil - } - return fmt.Errorf("Unable to load config version ‘1’. %v", err) + configFile := filepath.Join(getConfigDir(), "fsUsers.json") - } - - if cv1.Version == "1" { - // Purge old fsUsers.json file - configFile := filepath.Join(getConfigDir(), "fsUsers.json") - removeAll(configFile) - console.Println("Removed unsupported config version ‘1’.") + cv1 := &configV1{} + _, err := quick.Load(configFile, cv1) + if os.IsNotExist(err) { return nil + } else if err != nil { + return fmt.Errorf("Unable to load config version ‘1’. %v", err) } - return fmt.Errorf("Failed to migrate unrecognized config version ‘" + cv1.Version + "’.") + if cv1.Version != "1" { + return fmt.Errorf("unrecognized config version ‘%s’", cv1.Version) + } + + removeAll(configFile) + console.Println("Removed unsupported config version ‘1’.") + return nil } // Version '2' to '3' config migration adds new fields and re-orders // previous fields. Simplifies config for future additions. func migrateV2ToV3() error { - cv2, err := loadConfigV2() - if err != nil { - if os.IsNotExist(err) { - return nil - } + configFile := getConfigFile() + + cv2 := &configV2{} + _, err := quick.Load(configFile, cv2) + if os.IsNotExist(err) { + return nil + } else if err != nil { return fmt.Errorf("Unable to load config version ‘2’. %v", err) } if cv2.Version != "2" { @@ -155,18 +156,11 @@ func migrateV2ToV3() error { } srvConfig.Logger.Syslog = slogger - qc, err := quick.New(srvConfig) - if err != nil { - return fmt.Errorf("Unable to initialize config. %v", err) + if err = quick.Save(configFile, srvConfig); err != nil { + return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv2.Version, srvConfig.Version, err) } - configFile := getConfigFile() - err = qc.Save(configFile) - if err != nil { - return fmt.Errorf("Failed to migrate config from ‘"+cv2.Version+"’ to ‘"+srvConfig.Version+"’ failed. %v", err) - } - - console.Println("Migration from version ‘" + cv2.Version + "’ to ‘" + srvConfig.Version + "’ completed successfully.") + console.Printf("Migration from version ‘%s’ to ‘%s’ completed successfully.\n", cv2.Version, srvConfig.Version) return nil } @@ -174,11 +168,13 @@ func migrateV2ToV3() error { // to backend types and server address. This change further simplifies // the config for future additions. func migrateV3ToV4() error { - cv3, err := loadConfigV3() - if err != nil { - if os.IsNotExist(err) { - return nil - } + configFile := getConfigFile() + + cv3 := &configV3{} + _, err := quick.Load(configFile, cv3) + if os.IsNotExist(err) { + return nil + } else if err != nil { return fmt.Errorf("Unable to load config version ‘3’. %v", err) } if cv3.Version != "3" { @@ -198,18 +194,11 @@ func migrateV3ToV4() error { srvConfig.Logger.File = cv3.Logger.File srvConfig.Logger.Syslog = cv3.Logger.Syslog - qc, err := quick.New(srvConfig) - if err != nil { - return fmt.Errorf("Unable to initialize the quick config. %v", err) + if err = quick.Save(configFile, srvConfig); err != nil { + return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv3.Version, srvConfig.Version, err) } - configFile := getConfigFile() - err = qc.Save(configFile) - if err != nil { - return fmt.Errorf("Failed to migrate config from ‘"+cv3.Version+"’ to ‘"+srvConfig.Version+"’ failed. %v", err) - } - - console.Println("Migration from version ‘" + cv3.Version + "’ to ‘" + srvConfig.Version + "’ completed successfully.") + console.Printf("Migration from version ‘%s’ to ‘%s’ completed successfully.\n", cv3.Version, srvConfig.Version) return nil } @@ -217,11 +206,13 @@ func migrateV3ToV4() error { // to backend types and server address. This change further simplifies // the config for future additions. func migrateV4ToV5() error { - cv4, err := loadConfigV4() - if err != nil { - if os.IsNotExist(err) { - return nil - } + configFile := getConfigFile() + + cv4 := &configV4{} + _, err := quick.Load(configFile, cv4) + if os.IsNotExist(err) { + return nil + } else if err != nil { return fmt.Errorf("Unable to load config version ‘4’. %v", err) } if cv4.Version != "4" { @@ -244,18 +235,11 @@ func migrateV4ToV5() error { srvConfig.Logger.ElasticSearch.Enable = false srvConfig.Logger.Redis.Enable = false - qc, err := quick.New(srvConfig) - if err != nil { - return fmt.Errorf("Unable to initialize the quick config. %v", err) + if err = quick.Save(configFile, srvConfig); err != nil { + return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv4.Version, srvConfig.Version, err) } - configFile := getConfigFile() - err = qc.Save(configFile) - if err != nil { - return fmt.Errorf("Failed to migrate config from ‘"+cv4.Version+"’ to ‘"+srvConfig.Version+"’ failed. %v", err) - } - - console.Println("Migration from version ‘" + cv4.Version + "’ to ‘" + srvConfig.Version + "’ completed successfully.") + console.Printf("Migration from version ‘%s’ to ‘%s’ completed successfully.\n", cv4.Version, srvConfig.Version) return nil } @@ -263,11 +247,13 @@ func migrateV4ToV5() error { // to backend types and server address. This change further simplifies // the config for future additions. func migrateV5ToV6() error { - cv5, err := loadConfigV5() - if err != nil { - if os.IsNotExist(err) { - return nil - } + configFile := getConfigFile() + + cv5 := &configV5{} + _, err := quick.Load(configFile, cv5) + if os.IsNotExist(err) { + return nil + } else if err != nil { return fmt.Errorf("Unable to load config version ‘5’. %v", err) } if cv5.Version != "5" { @@ -317,18 +303,11 @@ func migrateV5ToV6() error { }, } - qc, err := quick.New(srvConfig) - if err != nil { - return fmt.Errorf("Unable to initialize the quick config. %v", err) + if err = quick.Save(configFile, srvConfig); err != nil { + return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv5.Version, srvConfig.Version, err) } - configFile := getConfigFile() - err = qc.Save(configFile) - if err != nil { - return fmt.Errorf("Failed to migrate config from ‘"+cv5.Version+"’ to ‘"+srvConfig.Version+"’ failed. %v", err) - } - - console.Println("Migration from version ‘" + cv5.Version + "’ to ‘" + srvConfig.Version + "’ completed successfully.") + console.Printf("Migration from version ‘%s’ to ‘%s’ completed successfully.\n", cv5.Version, srvConfig.Version) return nil } @@ -336,11 +315,13 @@ func migrateV5ToV6() error { // to backend types and server address. This change further simplifies // the config for future additions. func migrateV6ToV7() error { - cv6, err := loadConfigV6() - if err != nil { - if os.IsNotExist(err) { - return nil - } + configFile := getConfigFile() + + cv6 := &configV6{} + _, err := quick.Load(configFile, cv6) + if os.IsNotExist(err) { + return nil + } else if err != nil { return fmt.Errorf("Unable to load config version ‘6’. %v", err) } if cv6.Version != "6" { @@ -378,18 +359,11 @@ func migrateV6ToV7() error { srvConfig.Notify.Redis = cv6.Notify.Redis } - qc, err := quick.New(srvConfig) - if err != nil { - return fmt.Errorf("Unable to initialize the quick config. %v", err) + if err = quick.Save(configFile, srvConfig); err != nil { + return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv6.Version, srvConfig.Version, err) } - configFile := getConfigFile() - err = qc.Save(configFile) - if err != nil { - return fmt.Errorf("Failed to migrate config from ‘"+cv6.Version+"’ to ‘"+srvConfig.Version+"’ failed. %v", err) - } - - console.Println("Migration from version ‘" + cv6.Version + "’ to ‘" + srvConfig.Version + "’ completed successfully.") + console.Printf("Migration from version ‘%s’ to ‘%s’ completed successfully.\n", cv6.Version, srvConfig.Version) return nil } @@ -397,11 +371,13 @@ func migrateV6ToV7() error { // to backend types and server address. This change further simplifies // the config for future additions. func migrateV7ToV8() error { - cv7, err := loadConfigV7() - if err != nil { - if os.IsNotExist(err) { - return nil - } + configFile := getConfigFile() + + cv7 := &serverConfigV7{} + _, err := quick.Load(configFile, cv7) + if os.IsNotExist(err) { + return nil + } else if err != nil { return fmt.Errorf("Unable to load config version ‘7’. %v", err) } if cv7.Version != "7" { @@ -446,29 +422,24 @@ func migrateV7ToV8() error { srvConfig.Notify.Redis = cv7.Notify.Redis } - qc, err := quick.New(srvConfig) - if err != nil { - return fmt.Errorf("Unable to initialize the quick config. %v", err) + if err = quick.Save(configFile, srvConfig); err != nil { + return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv7.Version, srvConfig.Version, err) } - configFile := getConfigFile() - err = qc.Save(configFile) - if err != nil { - return fmt.Errorf("Failed to migrate config from ‘"+cv7.Version+"’ to ‘"+srvConfig.Version+"’ failed. %v", err) - } - - console.Println("Migration from version ‘" + cv7.Version + "’ to ‘" + srvConfig.Version + "’ completed successfully.") + console.Printf("Migration from version ‘%s’ to ‘%s’ completed successfully.\n", cv7.Version, srvConfig.Version) return nil } // Version '8' to '9' migration. Adds postgresql notifier // configuration, but it's otherwise the same as V8. func migrateV8ToV9() error { - cv8, err := loadConfigV8() - if err != nil { - if os.IsNotExist(err) { - return nil - } + configFile := getConfigFile() + + cv8 := &serverConfigV8{} + _, err := quick.Load(configFile, cv8) + if os.IsNotExist(err) { + return nil + } else if err != nil { return fmt.Errorf("Unable to load config version ‘8’. %v", err) } if cv8.Version != "8" { @@ -521,38 +492,24 @@ func migrateV8ToV9() error { srvConfig.Notify.PostgreSQL = cv8.Notify.PostgreSQL } - qc, err := quick.New(srvConfig) - if err != nil { - return fmt.Errorf("Unable to initialize the quick config. %v", - err) + if err = quick.Save(configFile, srvConfig); err != nil { + return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv8.Version, srvConfig.Version, err) } - configFile := getConfigFile() - err = qc.Save(configFile) - if err != nil { - return fmt.Errorf( - "Failed to migrate config from ‘"+ - cv8.Version+"’ to ‘"+srvConfig.Version+ - "’ failed. %v", err, - ) - } - - console.Println( - "Migration from version ‘" + - cv8.Version + "’ to ‘" + srvConfig.Version + - "’ completed successfully.", - ) + console.Printf("Migration from version ‘%s’ to ‘%s’ completed successfully.\n", cv8.Version, srvConfig.Version) return nil } // Version '9' to '10' migration. Remove syslog config // but it's otherwise the same as V9. func migrateV9ToV10() error { - cv9, err := loadConfigV9() - if err != nil { - if os.IsNotExist(err) { - return nil - } + configFile := getConfigFile() + + cv9 := &serverConfigV9{} + _, err := quick.Load(configFile, cv9) + if os.IsNotExist(err) { + return nil + } else if err != nil { return fmt.Errorf("Unable to load config version ‘9’. %v", err) } if cv9.Version != "9" { @@ -603,38 +560,24 @@ func migrateV9ToV10() error { srvConfig.Notify.PostgreSQL = cv9.Notify.PostgreSQL } - qc, err := quick.New(srvConfig) - if err != nil { - return fmt.Errorf("Unable to initialize the quick config. %v", - err) + if err = quick.Save(configFile, srvConfig); err != nil { + return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv9.Version, srvConfig.Version, err) } - configFile := getConfigFile() - err = qc.Save(configFile) - if err != nil { - return fmt.Errorf( - "Failed to migrate config from ‘"+ - cv9.Version+"’ to ‘"+srvConfig.Version+ - "’ failed. %v", err, - ) - } - - console.Println( - "Migration from version ‘" + - cv9.Version + "’ to ‘" + srvConfig.Version + - "’ completed successfully.", - ) + console.Printf("Migration from version ‘%s’ to ‘%s’ completed successfully.\n", cv9.Version, srvConfig.Version) return nil } // Version '10' to '11' migration. Add support for Kafka // notifications. func migrateV10ToV11() error { - cv10, err := loadConfigV10() - if err != nil { - if os.IsNotExist(err) { - return nil - } + configFile := getConfigFile() + + cv10 := &serverConfigV10{} + _, err := quick.Load(configFile, cv10) + if os.IsNotExist(err) { + return nil + } else if err != nil { return fmt.Errorf("Unable to load config version ‘10’. %v", err) } if cv10.Version != "10" { @@ -688,38 +631,24 @@ func migrateV10ToV11() error { srvConfig.Notify.Kafka = make(map[string]kafkaNotify) srvConfig.Notify.Kafka["1"] = kafkaNotify{} - qc, err := quick.New(srvConfig) - if err != nil { - return fmt.Errorf("Unable to initialize the quick config. %v", - err) + if err = quick.Save(configFile, srvConfig); err != nil { + return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv10.Version, srvConfig.Version, err) } - configFile := getConfigFile() - err = qc.Save(configFile) - if err != nil { - return fmt.Errorf( - "Failed to migrate config from ‘"+ - cv10.Version+"’ to ‘"+srvConfig.Version+ - "’ failed. %v", err, - ) - } - - console.Println( - "Migration from version ‘" + - cv10.Version + "’ to ‘" + srvConfig.Version + - "’ completed successfully.", - ) + console.Printf("Migration from version ‘%s’ to ‘%s’ completed successfully.\n", cv10.Version, srvConfig.Version) return nil } // Version '11' to '12' migration. Add support for NATS streaming // notifications. func migrateV11ToV12() error { - cv11, err := loadConfigV11() - if err != nil { - if os.IsNotExist(err) { - return nil - } + configFile := getConfigFile() + + cv11 := &serverConfigV11{} + _, err := quick.Load(configFile, cv11) + if os.IsNotExist(err) { + return nil + } else if err != nil { return fmt.Errorf("Unable to load config version ‘11’. %v", err) } if cv11.Version != "11" { @@ -791,37 +720,23 @@ func migrateV11ToV12() error { } } - qc, err := quick.New(srvConfig) - if err != nil { - return fmt.Errorf("Unable to initialize the quick config. %v", - err) + if err = quick.Save(configFile, srvConfig); err != nil { + return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv11.Version, srvConfig.Version, err) } - configFile := getConfigFile() - err = qc.Save(configFile) - if err != nil { - return fmt.Errorf( - "Failed to migrate config from ‘"+ - cv11.Version+"’ to ‘"+srvConfig.Version+ - "’ failed. %v", err, - ) - } - - console.Println( - "Migration from version ‘" + - cv11.Version + "’ to ‘" + srvConfig.Version + - "’ completed successfully.", - ) + console.Printf("Migration from version ‘%s’ to ‘%s’ completed successfully.\n", cv11.Version, srvConfig.Version) return nil } // Version '12' to '13' migration. Add support for custom webhook endpoint. func migrateV12ToV13() error { - cv12, err := loadConfigV12() - if err != nil { - if os.IsNotExist(err) { - return nil - } + configFile := getConfigFile() + + cv12 := &serverConfigV12{} + _, err := quick.Load(configFile, cv12) + if os.IsNotExist(err) { + return nil + } else if err != nil { return fmt.Errorf("Unable to load config version ‘12’. %v", err) } if cv12.Version != "12" { @@ -885,37 +800,23 @@ func migrateV12ToV13() error { srvConfig.Notify.Webhook = make(map[string]webhookNotify) srvConfig.Notify.Webhook["1"] = webhookNotify{} - qc, err := quick.New(srvConfig) - if err != nil { - return fmt.Errorf("Unable to initialize the quick config. %v", - err) + if err = quick.Save(configFile, srvConfig); err != nil { + return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv12.Version, srvConfig.Version, err) } - configFile := getConfigFile() - err = qc.Save(configFile) - if err != nil { - return fmt.Errorf( - "Failed to migrate config from ‘"+ - cv12.Version+"’ to ‘"+srvConfig.Version+ - "’ failed. %v", err, - ) - } - - console.Println( - "Migration from version ‘" + - cv12.Version + "’ to ‘" + srvConfig.Version + - "’ completed successfully.", - ) + console.Printf("Migration from version ‘%s’ to ‘%s’ completed successfully.\n", cv12.Version, srvConfig.Version) return nil } // Version '13' to '14' migration. Add support for browser param. func migrateV13ToV14() error { - cv13, err := loadConfigV13() - if err != nil { - if os.IsNotExist(err) { - return nil - } + configFile := getConfigFile() + + cv13 := &serverConfigV13{} + _, err := quick.Load(configFile, cv13) + if os.IsNotExist(err) { + return nil + } else if err != nil { return fmt.Errorf("Unable to load config version ‘13’. %v", err) } if cv13.Version != "13" { @@ -984,37 +885,23 @@ func migrateV13ToV14() error { // Set the new browser parameter to true by default srvConfig.Browser = "on" - qc, err := quick.New(srvConfig) - if err != nil { - return fmt.Errorf("Unable to initialize the quick config. %v", - err) + if err = quick.Save(configFile, srvConfig); err != nil { + return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv13.Version, srvConfig.Version, err) } - configFile := getConfigFile() - err = qc.Save(configFile) - if err != nil { - return fmt.Errorf( - "Failed to migrate config from ‘"+ - cv13.Version+"’ to ‘"+srvConfig.Version+ - "’ failed. %v", err, - ) - } - - console.Println( - "Migration from version ‘" + - cv13.Version + "’ to ‘" + srvConfig.Version + - "’ completed successfully.", - ) + console.Printf("Migration from version ‘%s’ to ‘%s’ completed successfully.\n", cv13.Version, srvConfig.Version) return nil } // Version '14' to '15' migration. Add support for MySQL notifications. func migrateV14ToV15() error { - cv14, err := loadConfigV14() - if err != nil { - if os.IsNotExist(err) { - return nil - } + configFile := getConfigFile() + + cv14 := &serverConfigV14{} + _, err := quick.Load(configFile, cv14) + if os.IsNotExist(err) { + return nil + } else if err != nil { return fmt.Errorf("Unable to load config version ‘14’. %v", err) } if cv14.Version != "14" { @@ -1087,26 +974,10 @@ func migrateV14ToV15() error { // Load browser config from existing config in the file. srvConfig.Browser = cv14.Browser - qc, err := quick.New(srvConfig) - if err != nil { - return fmt.Errorf("Unable to initialize the quick config. %v", - err) + if err = quick.Save(configFile, srvConfig); err != nil { + return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv14.Version, srvConfig.Version, err) } - configFile := getConfigFile() - err = qc.Save(configFile) - if err != nil { - return fmt.Errorf( - "Failed to migrate config from ‘"+ - cv14.Version+"’ to ‘"+srvConfig.Version+ - "’ failed. %v", err, - ) - } - - console.Println( - "Migration from version ‘" + - cv14.Version + "’ to ‘" + srvConfig.Version + - "’ completed successfully.", - ) + console.Printf("Migration from version ‘%s’ to ‘%s’ completed successfully.\n", cv14.Version, srvConfig.Version) return nil } diff --git a/cmd/config-old.go b/cmd/config-old.go index 89b397ff0..720f6f9ea 100644 --- a/cmd/config-old.go +++ b/cmd/config-old.go @@ -16,30 +16,7 @@ package cmd -import ( - "os" - "path/filepath" - "sync" - - "github.com/minio/minio/pkg/quick" -) - -func loadOldConfig(configFile string, config interface{}) (interface{}, error) { - if _, err := os.Stat(configFile); err != nil { - return nil, err - } - - qc, err := quick.New(config) - if err != nil { - return nil, err - } - - if err = qc.Load(configFile); err != nil { - return nil, err - } - - return config, nil -} +import "sync" /////////////////// Config V1 /////////////////// type configV1 struct { @@ -48,16 +25,6 @@ type configV1 struct { SecretKey string `json:"secretAccessKey"` } -// loadConfigV1 load config -func loadConfigV1() (*configV1, error) { - configFile := filepath.Join(getConfigDir(), "fsUsers.json") - config, err := loadOldConfig(configFile, &configV1{Version: "1"}) - if config == nil { - return nil, err - } - return config.(*configV1), err -} - /////////////////// Config V2 /////////////////// type configV2 struct { Version string `json:"version"` @@ -80,18 +47,7 @@ type configV2 struct { } `json:"fileLogger"` } -// loadConfigV2 load config version '2'. -func loadConfigV2() (*configV2, error) { - configFile := getConfigFile() - config, err := loadOldConfig(configFile, &configV2{Version: "2"}) - if config == nil { - return nil, err - } - return config.(*configV2), err -} - /////////////////// Config V3 /////////////////// - // backendV3 type. type backendV3 struct { Type string `json:"type"` @@ -143,16 +99,6 @@ type configV3 struct { Logger loggerV3 `json:"logger"` } -// loadConfigV3 load config version '3'. -func loadConfigV3() (*configV3, error) { - configFile := getConfigFile() - config, err := loadOldConfig(configFile, &configV3{Version: "3"}) - if config == nil { - return nil, err - } - return config.(*configV3), err -} - // logger type representing version '4' logger config. type loggerV4 struct { Console struct { @@ -183,16 +129,6 @@ type configV4 struct { Logger loggerV4 `json:"logger"` } -// loadConfigV4 load config version '4'. -func loadConfigV4() (*configV4, error) { - configFile := getConfigFile() - config, err := loadOldConfig(configFile, &configV4{Version: "4"}) - if config == nil { - return nil, err - } - return config.(*configV4), err -} - // logger type representing version '5' logger config. type loggerV5 struct { Console struct { @@ -250,16 +186,6 @@ type configV5 struct { Logger loggerV5 `json:"logger"` } -// loadConfigV5 load config version '5'. -func loadConfigV5() (*configV5, error) { - configFile := getConfigFile() - config, err := loadOldConfig(configFile, &configV5{Version: "5"}) - if config == nil { - return nil, err - } - return config.(*configV5), err -} - type loggerV6 struct { Console consoleLogger `json:"console"` File fileLogger `json:"file"` @@ -281,16 +207,6 @@ type configV6 struct { Notify notifierV1 `json:"notify"` } -// loadConfigV6 load config version '6'. -func loadConfigV6() (*configV6, error) { - configFile := getConfigFile() - config, err := loadOldConfig(configFile, &configV6{Version: "6"}) - if config == nil { - return nil, err - } - return config.(*configV6), err -} - // Notifier represents collection of supported notification queues in version // 1 without NATS streaming. type notifierV1 struct { @@ -331,16 +247,6 @@ type serverConfigV7 struct { rwMutex *sync.RWMutex } -// loadConfigV7 load config version '7'. -func loadConfigV7() (*serverConfigV7, error) { - configFile := getConfigFile() - config, err := loadOldConfig(configFile, &serverConfigV7{Version: "7"}) - if config == nil { - return nil, err - } - return config.(*serverConfigV7), err -} - // serverConfigV8 server configuration version '8'. Adds NATS notifier // configuration. type serverConfigV8 struct { @@ -360,16 +266,6 @@ type serverConfigV8 struct { rwMutex *sync.RWMutex } -// loadConfigV8 load config version '8'. -func loadConfigV8() (*serverConfigV8, error) { - configFile := getConfigFile() - config, err := loadOldConfig(configFile, &serverConfigV8{Version: "8"}) - if config == nil { - return nil, err - } - return config.(*serverConfigV8), err -} - // serverConfigV9 server configuration version '9'. Adds PostgreSQL // notifier configuration. type serverConfigV9 struct { @@ -389,15 +285,6 @@ type serverConfigV9 struct { rwMutex *sync.RWMutex } -func loadConfigV9() (*serverConfigV9, error) { - configFile := getConfigFile() - config, err := loadOldConfig(configFile, &serverConfigV9{Version: "9"}) - if config == nil { - return nil, err - } - return config.(*serverConfigV9), err -} - // serverConfigV10 server configuration version '10' which is like // version '9' except it drops support of syslog config, and makes the // RWMutex global (so it does not exist in this struct). @@ -415,15 +302,6 @@ type serverConfigV10 struct { Notify notifierV1 `json:"notify"` } -func loadConfigV10() (*serverConfigV10, error) { - configFile := getConfigFile() - config, err := loadOldConfig(configFile, &serverConfigV10{Version: "10"}) - if config == nil { - return nil, err - } - return config.(*serverConfigV10), err -} - // natsNotifyV1 - structure was valid until config V 11 type natsNotifyV1 struct { Enable bool `json:"enable"` @@ -452,15 +330,6 @@ type serverConfigV11 struct { Notify notifierV1 `json:"notify"` } -func loadConfigV11() (*serverConfigV11, error) { - configFile := getConfigFile() - config, err := loadOldConfig(configFile, &serverConfigV11{Version: "11"}) - if config == nil { - return nil, err - } - return config.(*serverConfigV11), err -} - // serverConfigV12 server configuration version '12' which is like // version '11' except it adds support for NATS streaming notifications. type serverConfigV12 struct { @@ -477,15 +346,6 @@ type serverConfigV12 struct { Notify notifierV2 `json:"notify"` } -func loadConfigV12() (*serverConfigV12, error) { - configFile := getConfigFile() - config, err := loadOldConfig(configFile, &serverConfigV12{Version: "12"}) - if config == nil { - return nil, err - } - return config.(*serverConfigV12), err -} - // serverConfigV13 server configuration version '13' which is like // version '12' except it adds support for webhook notification. type serverConfigV13 struct { @@ -502,15 +362,6 @@ type serverConfigV13 struct { Notify *notifier `json:"notify"` } -func loadConfigV13() (*serverConfigV13, error) { - configFile := getConfigFile() - config, err := loadOldConfig(configFile, &serverConfigV13{Version: "13"}) - if config == nil { - return nil, err - } - return config.(*serverConfigV13), err -} - // serverConfigV14 server configuration version '14' which is like // version '13' except it adds support of browser param. type serverConfigV14 struct { @@ -527,12 +378,3 @@ type serverConfigV14 struct { // Notification queue configuration. Notify *notifier `json:"notify"` } - -func loadConfigV14() (*serverConfigV14, error) { - configFile := getConfigFile() - config, err := loadOldConfig(configFile, &serverConfigV14{Version: "14"}) - if config == nil { - return nil, err - } - return config.(*serverConfigV14), err -} diff --git a/cmd/config-v15.go b/cmd/config-v15.go index d81af8baf..dba4e38a1 100644 --- a/cmd/config-v15.go +++ b/cmd/config-v15.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "io/ioutil" - "os" "strings" "sync" @@ -32,7 +31,7 @@ import ( var serverConfigMu sync.RWMutex // Config version -var v15 = "15" +const v15 = "15" // serverConfigV15 server configuration version '15' which is like // version '14' except it adds support of MySQL notifications. @@ -122,19 +121,13 @@ func newConfig(envParams envParams) error { // if found and valid func loadConfig(envParams envParams) error { configFile := getConfigFile() - if _, err := os.Stat(configFile); err != nil { - return err - } srvCfg := &serverConfigV15{} - - qc, err := quick.New(srvCfg) - if err != nil { + if _, err := quick.Load(configFile, srvCfg); err != nil { return err } - - if err = qc.Load(configFile); err != nil { - return err + if srvCfg.Version != v15 { + return fmt.Errorf("configuration version mismatch. Expected: ‘%s’, Got: ‘%s’", srvCfg.Version, v15) } // If env is set override the credentials from config file. @@ -155,11 +148,6 @@ func loadConfig(envParams envParams) error { // Save the loaded config globally. serverConfig = srvCfg serverConfigMu.Unlock() - - if serverConfig.Version != v15 { - return errors.New("Unsupported config version `" + serverConfig.Version + "`.") - } - return nil } @@ -216,23 +204,15 @@ func checkDupJSONKeys(json string) error { // validateConfig checks for func validateConfig() error { - - // Get file config path configFile := getConfigFile() srvCfg := &serverConfigV15{} - - // Load config file - qc, err := quick.New(srvCfg) - if err != nil { - return err - } - if err = qc.Load(configFile); err != nil { + if _, err := quick.Load(configFile, srvCfg); err != nil { return err } // Check if config version is valid - if srvCfg.GetVersion() != v15 { + if srvCfg.Version != v15 { return errors.New("bad config version, expected: " + v15) } @@ -361,12 +341,6 @@ func (s serverConfigV15) Save() error { // get config file. configFile := getConfigFile() - // initialize quick. - qc, err := quick.New(&s) - if err != nil { - return err - } - // Save config file. - return qc.Save(configFile) + return quick.Save(configFile, &s) } diff --git a/pkg/quick/quick.go b/pkg/quick/quick.go index 26cae6983..55cecb5db 100644 --- a/pkg/quick/quick.go +++ b/pkg/quick/quick.go @@ -1,7 +1,7 @@ /* * Quick - Quick key value store for config files and persistent state files * - * Quick (C) 2015 Minio, Inc. + * Quick (C) 2015, 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,99 +47,11 @@ type config struct { lock *sync.RWMutex } -// CheckData - checks the validity of config data. Data should be of -// type struct and contain a string type field called "Version". -func CheckData(data interface{}) error { - if !structs.IsStruct(data) { - return fmt.Errorf("Invalid argument type. Expecing \"struct\" type") - } - - st := structs.New(data) - f, ok := st.FieldOk("Version") - if !ok { - return fmt.Errorf("Invalid type of struct argument. No [%s.Version] field found", st.Name()) - } - - if f.Kind() != reflect.String { - return fmt.Errorf("Invalid type of struct argument. Expecting \"string\" type [%s.Version] field", st.Name()) - } - - return nil -} - -// New - instantiate a new config -func New(data interface{}) (Config, error) { - if err := CheckData(data); err != nil { - return nil, err - } - - d := new(config) - d.data = data - d.lock = new(sync.RWMutex) - return d, nil -} - -// CheckVersion - loads json and compares the version number provided returns back true or false - any failure -// is returned as error. -func CheckVersion(filename string, version string) (bool, error) { - data := struct { - Version string - }{ - Version: "", - } - config, err := Load(filename, &data) - if err != nil { - return false, err - } - if config.Version() != version { - return false, nil - } - return true, nil -} - -// Load - loads json config from filename for the a given struct data -func Load(filename string, data interface{}) (Config, error) { - config, err := New(data) - if err != nil { - return nil, err - } - err = config.Load(filename) - if err != nil { - return nil, err - } - return config, nil -} - // Version returns the current config file format version func (d config) Version() string { st := structs.New(d.data) - - f, ok := st.FieldOk("Version") - if !ok { - return "" - } - - val := f.Value() - ver, ok := val.(string) - if ok { - return ver - } - return "" -} - -// writeFile writes data to a file named by filename. -// If the file does not exist, writeFile creates it; -// otherwise writeFile truncates it before writing. -func writeFile(filename string, data []byte) error { - safeFile, err := safe.CreateFile(filename) - if err != nil { - return err - } - _, err = safeFile.Write(data) - if err != nil { - return err - } - return safeFile.Close() + f := st.Field("Version") + return f.Value().(string) } // String converts JSON config to printable string @@ -155,26 +67,17 @@ func (d config) Save(filename string) error { d.lock.Lock() defer d.lock.Unlock() - // Check for existing file, if yes create a backup. - st, err := os.Stat(filename) - // If file exists and stat failed return here. - if err != nil && !os.IsNotExist(err) { - return err - } - // File exists and proceed to take backup. - if err == nil { - // File exists and is not a regular file return error. - if !st.Mode().IsRegular() { - return fmt.Errorf("%s is not a regular file", filename) - } - // Read old data. - var oldData []byte - oldData, err = ioutil.ReadFile(filename) - if err != nil { + // Backup if given file exists + oldData, err := ioutil.ReadFile(filename) + if err != nil { + // Ignore if file does not exist. + if !os.IsNotExist(err) { return err } + } else { // Save read data to the backup file. - if err = writeFile(filename+".old", oldData); err != nil { + backupFilename := filename + ".old" + if err = writeFile(backupFilename, oldData); err != nil { return err } } @@ -186,28 +89,14 @@ func (d config) Save(filename string) error { // Load - loads config from file and merge with currently set values // File content format is guessed from the file name extension, if not // available, consider that we have JSON. -func (d *config) Load(filename string) error { +func (d config) Load(filename string) error { d.lock.Lock() defer d.lock.Unlock() - st := structs.New(d.data) - f, ok := st.FieldOk("Version") - if !ok { - return fmt.Errorf("Argument struct [%s] does not contain field \"Version\"", st.Name()) - } - if err := loadFileConfig(filename, d.data); err != nil { return err } - if err := CheckData(d.data); err != nil { - return err - } - - if (*d).Version() != f.Value() { - return fmt.Errorf("Version mismatch") - } - return nil } @@ -219,10 +108,6 @@ func (d config) Data() interface{} { //Diff - list fields that are in A but not in B func (d config) Diff(c Config) ([]structs.Field, error) { var fields []structs.Field - err := CheckData(c.Data()) - if err != nil { - return []structs.Field{}, err - } currFields := structs.Fields(d.Data()) newFields := structs.Fields(c.Data()) @@ -245,10 +130,6 @@ func (d config) Diff(c Config) ([]structs.Field, error) { //DeepDiff - list fields in A that are missing or not equal to fields in B func (d config) DeepDiff(c Config) ([]structs.Field, error) { var fields []structs.Field - err := CheckData(c.Data()) - if err != nil { - return []structs.Field{}, err - } currFields := structs.Fields(d.Data()) newFields := structs.Fields(c.Data()) @@ -267,3 +148,69 @@ func (d config) DeepDiff(c Config) ([]structs.Field, error) { } return fields, nil } + +// checkData - checks the validity of config data. Data should be of +// type struct and contain a string type field called "Version". +func checkData(data interface{}) error { + if !structs.IsStruct(data) { + return fmt.Errorf("interface must be struct type") + } + + st := structs.New(data) + f, ok := st.FieldOk("Version") + if !ok { + return fmt.Errorf("struct ‘%s’ must have field ‘Version’", st.Name()) + } + + if f.Kind() != reflect.String { + return fmt.Errorf("‘Version’ field in struct ‘%s’ must be a string type", st.Name()) + } + + return nil +} + +// writeFile writes data to a file named by filename. +// If the file does not exist, writeFile creates it; +// otherwise writeFile truncates it before writing. +func writeFile(filename string, data []byte) error { + safeFile, err := safe.CreateFile(filename) + if err != nil { + return err + } + _, err = safeFile.Write(data) + if err != nil { + return err + } + return safeFile.Close() +} + +// New - instantiate a new config +func New(data interface{}) (Config, error) { + if err := checkData(data); err != nil { + return nil, err + } + + d := new(config) + d.data = data + d.lock = new(sync.RWMutex) + return d, nil +} + +// Load - loads json config from filename for the a given struct data +func Load(filename string, data interface{}) (qc Config, err error) { + if qc, err = New(data); err == nil { + err = qc.Load(filename) + } + + return qc, err +} + +// Save - saves given configuration data into given file as JSON. +func Save(filename string, data interface{}) (err error) { + var qc Config + if qc, err = New(data); err == nil { + err = qc.Save(filename) + } + + return err +} diff --git a/pkg/quick/quick_test.go b/pkg/quick/quick_test.go index 561255af3..aed6b1d49 100644 --- a/pkg/quick/quick_test.go +++ b/pkg/quick/quick_test.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package quick_test +package quick import ( "encoding/json" @@ -27,7 +27,6 @@ import ( "strings" "testing" - "github.com/minio/minio/pkg/quick" . "gopkg.in/check.v1" ) @@ -45,7 +44,7 @@ func (s *MySuite) TestSaveFailOnDir(c *C) { Version string } saveMe := myStruct{"1"} - config, err := quick.New(&saveMe) + config, err := New(&saveMe) c.Assert(err, IsNil) c.Assert(config, Not(IsNil)) err = config.Save("test.json") @@ -53,7 +52,7 @@ func (s *MySuite) TestSaveFailOnDir(c *C) { } func (s *MySuite) TestCheckData(c *C) { - err := quick.CheckData(nil) + err := checkData(nil) c.Assert(err, Not(IsNil)) type myStructBadNoVersion struct { @@ -62,7 +61,7 @@ func (s *MySuite) TestCheckData(c *C) { Directories []string } saveMeBadNoVersion := myStructBadNoVersion{"guest", "nopassword", []string{"Work", "Documents", "Music"}} - err = quick.CheckData(&saveMeBadNoVersion) + err = checkData(&saveMeBadNoVersion) c.Assert(err, Not(IsNil)) type myStructBadVersionInt struct { @@ -71,7 +70,7 @@ func (s *MySuite) TestCheckData(c *C) { Password string } saveMeBadVersionInt := myStructBadVersionInt{1, "guest", "nopassword"} - err = quick.CheckData(&saveMeBadVersionInt) + err = checkData(&saveMeBadVersionInt) c.Assert(err, Not(IsNil)) type myStructGood struct { @@ -82,7 +81,7 @@ func (s *MySuite) TestCheckData(c *C) { } saveMeGood := myStructGood{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - err = quick.CheckData(&saveMeGood) + err = checkData(&saveMeGood) c.Assert(err, IsNil) } @@ -94,15 +93,15 @@ func (s *MySuite) TestLoadFile(c *C) { Directories []string } saveMe := myStruct{} - _, err := quick.Load("test.json", &saveMe) + _, err := Load("test.json", &saveMe) c.Assert(err, Not(IsNil)) file, err := os.Create("test.json") c.Assert(err, IsNil) c.Assert(file.Close(), IsNil) - _, err = quick.Load("test.json", &saveMe) + _, err = Load("test.json", &saveMe) c.Assert(err, Not(IsNil)) - config, err := quick.New(&saveMe) + config, err := New(&saveMe) c.Assert(err, IsNil) err = config.Load("test-non-exist.json") c.Assert(err, Not(IsNil)) @@ -110,13 +109,13 @@ func (s *MySuite) TestLoadFile(c *C) { c.Assert(err, Not(IsNil)) saveMe = myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err = quick.New(&saveMe) + config, err = New(&saveMe) c.Assert(err, IsNil) c.Assert(config, Not(IsNil)) err = config.Save("test.json") c.Assert(err, IsNil) saveMe1 := myStruct{} - _, err = quick.Load("test.json", &saveMe1) + _, err = Load("test.json", &saveMe1) c.Assert(err, IsNil) c.Assert(saveMe1, DeepEquals, saveMe) @@ -153,7 +152,7 @@ directories: saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} // Save format using - config, err := quick.New(&saveMe) + config, err := New(&saveMe) c.Assert(err, IsNil) c.Assert(config, Not(IsNil)) @@ -168,7 +167,7 @@ directories: // Check if the loaded data is the same as the saved one loadMe := myStruct{} - config, err = quick.New(&loadMe) + config, err = New(&loadMe) err = config.Load(testYAML) c.Assert(err, IsNil) @@ -204,7 +203,7 @@ func (s *MySuite) TestJSONFormat(c *C) { saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} // Save format using - config, err := quick.New(&saveMe) + config, err := New(&saveMe) c.Assert(err, IsNil) c.Assert(config, Not(IsNil)) @@ -219,46 +218,13 @@ func (s *MySuite) TestJSONFormat(c *C) { // Check if the loaded data is the same as the saved one loadMe := myStruct{} - config, err = quick.New(&loadMe) + config, err = New(&loadMe) err = config.Load(testJSON) c.Assert(err, IsNil) c.Assert(reflect.DeepEqual(saveMe, loadMe), Equals, true) } -func (s *MySuite) TestVersion(c *C) { - defer os.RemoveAll("test.json") - type myStruct struct { - Version string - User string - Password string - Directories []string - } - saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err := quick.New(&saveMe) - c.Assert(err, IsNil) - c.Assert(config, Not(IsNil)) - err = config.Save("test.json") - c.Assert(err, IsNil) - - valid, err := quick.CheckVersion("test.json", "1") - c.Assert(err, IsNil) - c.Assert(valid, Equals, true) - - valid, err = quick.CheckVersion("test.json", "2") - c.Assert(err, IsNil) - c.Assert(valid, Equals, false) - - _, err = quick.CheckVersion("test1.json", "1") - c.Assert(err, Not(IsNil)) - - file, err := os.Create("test.json") - c.Assert(err, IsNil) - c.Assert(file.Close(), IsNil) - _, err = quick.CheckVersion("test.json", "1") - c.Assert(err, Not(IsNil)) -} - func (s *MySuite) TestSaveLoad(c *C) { defer os.RemoveAll("test.json") type myStruct struct { @@ -268,14 +234,14 @@ func (s *MySuite) TestSaveLoad(c *C) { Directories []string } saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err := quick.New(&saveMe) + config, err := New(&saveMe) c.Assert(err, IsNil) c.Assert(config, Not(IsNil)) err = config.Save("test.json") c.Assert(err, IsNil) loadMe := myStruct{Version: "1"} - newConfig, err := quick.New(&loadMe) + newConfig, err := New(&loadMe) c.Assert(err, IsNil) c.Assert(newConfig, Not(IsNil)) err = newConfig.Load("test.json") @@ -298,14 +264,14 @@ func (s *MySuite) TestSaveBackup(c *C) { Directories []string } saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err := quick.New(&saveMe) + config, err := New(&saveMe) c.Assert(err, IsNil) c.Assert(config, Not(IsNil)) err = config.Save("test.json") c.Assert(err, IsNil) loadMe := myStruct{Version: "1"} - newConfig, err := quick.New(&loadMe) + newConfig, err := New(&loadMe) c.Assert(err, IsNil) c.Assert(newConfig, Not(IsNil)) err = newConfig.Load("test.json") @@ -316,7 +282,7 @@ func (s *MySuite) TestSaveBackup(c *C) { mismatch := myStruct{"1.1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} c.Assert(newConfig.Data(), Not(DeepEquals), &mismatch) - config, err = quick.New(&mismatch) + config, err = New(&mismatch) c.Assert(err, IsNil) c.Assert(config, Not(IsNil)) err = config.Save("test.json") @@ -331,7 +297,7 @@ func (s *MySuite) TestDiff(c *C) { Directories []string } saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err := quick.New(&saveMe) + config, err := New(&saveMe) c.Assert(err, IsNil) c.Assert(config, Not(IsNil)) @@ -343,7 +309,7 @@ func (s *MySuite) TestDiff(c *C) { } mismatch := myNewStruct{"1", "nopassword", []string{"Work", "documents", "Music"}} - newConfig, err := quick.New(&mismatch) + newConfig, err := New(&mismatch) c.Assert(err, IsNil) c.Assert(newConfig, Not(IsNil)) @@ -365,12 +331,12 @@ func (s *MySuite) TestDeepDiff(c *C) { Directories []string } saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err := quick.New(&saveMe) + config, err := New(&saveMe) c.Assert(err, IsNil) c.Assert(config, Not(IsNil)) mismatch := myStruct{"1", "Guest", "nopassword", []string{"Work", "documents", "Music"}} - newConfig, err := quick.New(&mismatch) + newConfig, err := New(&mismatch) c.Assert(err, IsNil) c.Assert(newConfig, Not(IsNil))