From 481390d51abb9194496f5e926e477115edcddfbc Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 23 Apr 2018 11:05:56 -0700 Subject: [PATCH] Converge etcd functionality as part of quick.Config --- cmd/common-main.go | 8 +- cmd/config-current.go | 27 +--- cmd/config-migrate.go | 4 +- cmd/globals.go | 4 +- docs/federation/lookup/README.md | 18 +-- pkg/dns/coredns.go | 14 +-- pkg/quick/encoding.go | 52 ++++++++ pkg/quick/quick.go | 88 +++++++------ pkg/quick/quick_etcd.go | 204 ------------------------------- pkg/quick/quick_test.go | 52 ++++---- 10 files changed, 159 insertions(+), 312 deletions(-) delete mode 100644 pkg/quick/quick_etcd.go diff --git a/cmd/common-main.go b/cmd/common-main.go index 4517339ac..100c5e6e2 100644 --- a/cmd/common-main.go +++ b/cmd/common-main.go @@ -27,7 +27,7 @@ import ( "strings" "time" - etcdc "github.com/coreos/etcd/client" + etcd "github.com/coreos/etcd/client" "github.com/minio/cli" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/auth" @@ -49,7 +49,7 @@ func checkUpdate(mode string) { // Initialize and load config from remote etcd or local config directory func initConfig() { if globalEtcdClient != nil { - kapi := etcdc.NewKeysAPI(globalEtcdClient) + kapi := etcd.NewKeysAPI(globalEtcdClient) ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) _, err := kapi.Get(ctx, getConfigFile(), nil) cancel() @@ -57,7 +57,7 @@ func initConfig() { logger.FatalIf(migrateConfig(), "Config migration failed.") logger.FatalIf(loadConfig(), "Unable to load config version: '%s'.", serverConfigVersion) } else { - if etcdc.IsKeyNotFound(err) { + if etcd.IsKeyNotFound(err) { logger.FatalIf(newConfig(), "Unable to initialize minio config for the first time.") logger.Info("Created minio configuration file successfully at", globalEtcdClient.Endpoints()) } else { @@ -154,7 +154,7 @@ func handleCommonEnvVars() { if ok { etcdEndpoints := strings.Split(etcdEndpointsEnv, ",") var err error - globalEtcdClient, err = etcdc.New(etcdc.Config{ + globalEtcdClient, err = etcd.New(etcd.Config{ Endpoints: etcdEndpoints, Transport: &http.Transport{ Proxy: http.ProxyFromEnvironment, diff --git a/cmd/config-current.go b/cmd/config-current.go index afe66abf1..713716abe 100644 --- a/cmd/config-current.go +++ b/cmd/config-current.go @@ -129,26 +129,17 @@ func (s *serverConfig) GetCacheConfig() CacheConfig { // Save config file to corresponding backend func Save(configFile string, data interface{}) error { - if globalEtcdClient == nil { - return quick.SaveLocalConfig(configFile, data) - } - return quick.SaveEtcdConfig(configFile, data, globalEtcdClient) + return quick.SaveConfig(data, configFile, globalEtcdClient) } // Load config from backend func Load(configFile string, data interface{}) (quick.Config, error) { - if globalEtcdClient == nil { - return quick.LoadLocalConfig(configFile, data) - } - return quick.LoadEtcdConfig(configFile, data, globalEtcdClient) + return quick.LoadConfig(configFile, globalEtcdClient, data) } // GetVersion gets config version from backend func GetVersion(configFile string) (string, error) { - if globalEtcdClient == nil { - return quick.GetLocalVersion(configFile) - } - return quick.GetEtcdVersion(configFile, globalEtcdClient) + return quick.GetVersion(configFile, globalEtcdClient) } // Returns the string describing a difference with the given @@ -296,17 +287,7 @@ func newConfig() error { // newQuickConfig - initialize a new server config, with an allocated // quick.Config interface. func newQuickConfig(srvCfg *serverConfig) (*serverConfig, error) { - if globalEtcdClient == nil { - qcfg, err := quick.NewLocalConfig(srvCfg) - if err != nil { - return nil, err - } - - srvCfg.Config = qcfg - return srvCfg, nil - } - - qcfg, err := quick.NewEtcdConfig(srvCfg, globalEtcdClient) + qcfg, err := quick.NewConfig(srvCfg, globalEtcdClient) if err != nil { return nil, err } diff --git a/cmd/config-migrate.go b/cmd/config-migrate.go index a84ebd749..113d8175c 100644 --- a/cmd/config-migrate.go +++ b/cmd/config-migrate.go @@ -21,7 +21,7 @@ import ( "os" "path/filepath" - etcdc "github.com/coreos/etcd/client" + etcd "github.com/coreos/etcd/client" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/auth" "github.com/minio/minio/pkg/event" @@ -195,7 +195,7 @@ func purgeV1() error { cv1 := &configV1{} _, err := Load(configFile, cv1) - if os.IsNotExist(err) || etcdc.IsKeyNotFound(err) { + if os.IsNotExist(err) || etcd.IsKeyNotFound(err) { return nil } else if err != nil { return fmt.Errorf("Unable to load config version ‘1’. %v", err) diff --git a/cmd/globals.go b/cmd/globals.go index 143c7a444..fe77012c6 100644 --- a/cmd/globals.go +++ b/cmd/globals.go @@ -22,7 +22,7 @@ import ( "runtime" "time" - etcdc "github.com/coreos/etcd/client" + etcd "github.com/coreos/etcd/client" humanize "github.com/dustin/go-humanize" "github.com/fatih/color" xhttp "github.com/minio/minio/cmd/http" @@ -200,7 +200,7 @@ var ( globalRPCAPIVersion = RPCVersion{3, 0, 0} // Allocated etcd endpoint for config and bucket DNS. - globalEtcdClient etcdc.Client + globalEtcdClient etcd.Client // Allocated DNS config wrapper over etcd client. globalDNSConfig dns.Config diff --git a/docs/federation/lookup/README.md b/docs/federation/lookup/README.md index 2c681935b..2cf7ee553 100644 --- a/docs/federation/lookup/README.md +++ b/docs/federation/lookup/README.md @@ -4,7 +4,7 @@ There are primarily two types of federation - Bucket lookup from DNS - Bucket is shared across many clusters -This document will explain in detail about how to configure Minio supporting `Bucket lookup` +This document will explain about how to configure Minio to support `Bucket lookup from DNS` style federation. ## Federation (Bucket Lookup) Bucket lookup federation requires two dependencies @@ -33,15 +33,17 @@ minio server http://rack{5...8}.host{5...8}.domain.com/mnt/export{1...32} ``` In this configuration you can see `MINIO_ETCD_ENDPOINTS` points to the etcd backend which manages Minio's -`config.json` and bucket SRV records. `MINIO_DOMAIN` indicates the domain suffix for the bucket which -will be used to resolve bucket from DNS. For example if you have a bucket such as `mybucket`, the -client can use now `mybucket.domain.com` to directly resolve to the right cluster. `MINIO_PUBLIC_IP` -points to the public IP address where each cluster might be accessible, this is unique per each cluster. +`config.json` and bucket DNS SRV records. `MINIO_DOMAIN` indicates the domain suffix for the bucket which +will be used to resolve bucket through DNS. For example if you have a bucket such as `mybucket`, the +client can use now `mybucket.domain.com` to directly resolve itself to the right cluster. `MINIO_PUBLIC_IP` +points to the public IP address where each cluster might be accessible, this is unique for each cluster. -NOTE: `mybucket` only exists on one cluster either `cluster1` or `cluster2` this is truly random and +NOTE: `mybucket` only exists on one cluster either `cluster1` or `cluster2` this is random and is decided by how `domain.com` gets resolved, if there is a round-robin DNS on `domain.com` then -it is truly random which cluster might provision the bucket. This control is not provided to the -client yet, but can be done based on the `region` parameter as supported by `AWS S3` specification. +it is randomized which cluster might provision the bucket. + +TODO: For now the control to create the bucket from a client to the right cluster using `region` paramter +is not implemented yet. diff --git a/pkg/dns/coredns.go b/pkg/dns/coredns.go index cc1e9a4ab..37b8a956b 100644 --- a/pkg/dns/coredns.go +++ b/pkg/dns/coredns.go @@ -28,7 +28,7 @@ import ( "time" "github.com/coredns/coredns/plugin/etcd/msg" - etcdc "github.com/coreos/etcd/client" + etcd "github.com/coreos/etcd/client" ) // create a new coredns service record for the bucket. @@ -43,7 +43,7 @@ func newCoreDNSMsg(bucket string, ip string, port int, ttl uint32) ([]byte, erro // Retrieves list of DNS entries for a bucket. func (c *coreDNS) List() ([]SrvRecord, error) { - kapi := etcdc.NewKeysAPI(c.etcdClient) + kapi := etcd.NewKeysAPI(c.etcdClient) key := msg.Path(fmt.Sprintf("%s.", c.domainName), defaultPrefixPath) ctx, cancel := context.WithTimeout(context.Background(), defaultContextTimeout) r, err := kapi.Get(ctx, key, nil) @@ -69,7 +69,7 @@ func (c *coreDNS) List() ([]SrvRecord, error) { // Retrieves DNS record for a bucket. func (c *coreDNS) Get(bucket string) (SrvRecord, error) { - kapi := etcdc.NewKeysAPI(c.etcdClient) + kapi := etcd.NewKeysAPI(c.etcdClient) key := msg.Path(fmt.Sprintf("%s.%s.", bucket, c.domainName), defaultPrefixPath) ctx, cancel := context.WithTimeout(context.Background(), defaultContextTimeout) r, err := kapi.Get(ctx, key, nil) @@ -91,7 +91,7 @@ func (c *coreDNS) Put(bucket string) error { if err != nil { return err } - kapi := etcdc.NewKeysAPI(c.etcdClient) + kapi := etcd.NewKeysAPI(c.etcdClient) key := msg.Path(fmt.Sprintf("%s.%s.", bucket, c.domainName), defaultPrefixPath) ctx, cancel := context.WithTimeout(context.Background(), defaultContextTimeout) _, err = kapi.Set(ctx, key, string(bucketMsg), nil) @@ -101,7 +101,7 @@ func (c *coreDNS) Put(bucket string) error { // Removes DNS entries added in Put(). func (c *coreDNS) Delete(bucket string) error { - kapi := etcdc.NewKeysAPI(c.etcdClient) + kapi := etcd.NewKeysAPI(c.etcdClient) key := msg.Path(fmt.Sprintf("%s.%s.", bucket, c.domainName), defaultPrefixPath) ctx, cancel := context.WithTimeout(context.Background(), defaultContextTimeout) _, err := kapi.Delete(ctx, key, nil) @@ -113,11 +113,11 @@ func (c *coreDNS) Delete(bucket string) error { type coreDNS struct { domainName, domainIP string domainPort int - etcdClient etcdc.Client + etcdClient etcd.Client } // NewCoreDNS - initialize a new coreDNS set/unset values. -func NewCoreDNS(domainName, domainIP, domainPort string, etcdClient etcdc.Client) (Config, error) { +func NewCoreDNS(domainName, domainIP, domainPort string, etcdClient etcd.Client) (Config, error) { if domainName == "" || domainIP == "" || etcdClient == nil { return nil, errors.New("invalid argument") } diff --git a/pkg/quick/encoding.go b/pkg/quick/encoding.go index c79a7eaa9..1bdf69405 100644 --- a/pkg/quick/encoding.go +++ b/pkg/quick/encoding.go @@ -20,6 +20,7 @@ package quick import ( "bytes" + "context" "encoding/json" "fmt" "io/ioutil" @@ -27,7 +28,9 @@ import ( "path/filepath" "runtime" "strings" + "time" + etcd "github.com/coreos/etcd/client" yaml "gopkg.in/yaml.v2" ) @@ -122,6 +125,55 @@ func saveFileConfig(filename string, v interface{}) error { } +func saveFileConfigEtcd(filename string, clnt etcd.Client, v interface{}) error { + // Fetch filename's extension + ext := filepath.Ext(filename) + // Marshal data + dataBytes, err := toMarshaller(ext)(v) + if err != nil { + return err + } + if runtime.GOOS == "windows" { + dataBytes = []byte(strings.Replace(string(dataBytes), "\n", "\r\n", -1)) + } + + kapi := etcd.NewKeysAPI(clnt) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) + _, err = kapi.Update(ctx, filename, string(dataBytes)) + cancel() + return err +} + +func loadFileConfigEtcd(filename string, clnt etcd.Client, v interface{}) error { + kapi := etcd.NewKeysAPI(clnt) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) + resp, err := kapi.Get(ctx, filename, nil) + cancel() + if err != nil { + return err + } + + var ev *etcd.Node + switch { + case resp.Node.Dir: + for _, ev = range resp.Node.Nodes { + if string(ev.Key) == filename { + break + } + } + default: + ev = resp.Node + } + + fileData := ev.Value + if runtime.GOOS == "windows" { + fileData = strings.Replace(ev.Value, "\r\n", "\n", -1) + } + + // Unmarshal file's content + return toUnmarshaller(filepath.Ext(filename))([]byte(fileData), v) +} + // loadFileConfig unmarshals the file's content with the right // decoder format according to the filename extension. If no // extension is provided, json will be selected by default. diff --git a/pkg/quick/quick.go b/pkg/quick/quick.go index 97c427645..63fd5e054 100644 --- a/pkg/quick/quick.go +++ b/pkg/quick/quick.go @@ -26,6 +26,7 @@ import ( "reflect" "sync" + etcd "github.com/coreos/etcd/client" "github.com/fatih/structs" "github.com/minio/minio/pkg/safe" ) @@ -41,21 +42,22 @@ type Config interface { DeepDiff(Config) ([]structs.Field, error) } -// localConfig - implements quick.Config interface -type localConfig struct { +// config - implements quick.Config interface +type config struct { data interface{} + clnt etcd.Client lock *sync.RWMutex } // Version returns the current config file format version -func (d localConfig) Version() string { +func (d config) Version() string { st := structs.New(d.data) f := st.Field("Version") return f.Value().(string) } // String converts JSON config to printable string -func (d localConfig) String() string { +func (d config) String() string { configBytes, _ := json.MarshalIndent(d.data, "", "\t") return string(configBytes) } @@ -63,10 +65,14 @@ func (d localConfig) String() string { // Save writes config data to a file. Data format // is selected based on file extension or JSON if // not provided. -func (d localConfig) Save(filename string) error { +func (d config) Save(filename string) error { d.lock.Lock() defer d.lock.Unlock() + if d.clnt != nil { + return saveFileConfigEtcd(filename, d.clnt, d.data) + } + // Backup if given file exists oldData, err := ioutil.ReadFile(filename) if err != nil { @@ -89,19 +95,22 @@ func (d localConfig) 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 localConfig) Load(filename string) error { +func (d config) Load(filename string) error { d.lock.Lock() defer d.lock.Unlock() + if d.clnt != nil { + return loadFileConfigEtcd(filename, d.clnt, d.data) + } return loadFileConfig(filename, d.data) } // Data - grab internal data map for reading -func (d localConfig) Data() interface{} { +func (d config) Data() interface{} { return d.data } // Diff - list fields that are in A but not in B -func (d localConfig) Diff(c Config) ([]structs.Field, error) { +func (d config) Diff(c Config) ([]structs.Field, error) { var fields []structs.Field currFields := structs.Fields(d.Data()) @@ -123,7 +132,7 @@ func (d localConfig) Diff(c Config) ([]structs.Field, error) { } // DeepDiff - list fields in A that are missing or not equal to fields in B -func (d localConfig) DeepDiff(c Config) ([]structs.Field, error) { +func (d config) DeepDiff(c Config) ([]structs.Field, error) { var fields []structs.Field currFields := structs.Fields(d.Data()) @@ -179,43 +188,50 @@ func writeFile(filename string, data []byte) error { return safeFile.Close() } -// NewLocalConfig - instantiate a new config r/w configs from local files. -func NewLocalConfig(data interface{}) (Config, error) { - if err := checkData(data); err != nil { - return nil, err - } - - d := new(localConfig) - d.data = data - d.lock = new(sync.RWMutex) - return d, nil -} - -// GetLocalVersion - extracts the version information. -func GetLocalVersion(filename string) (version string, err error) { +// GetVersion - extracts the version information. +func GetVersion(filename string, clnt etcd.Client) (version string, err error) { var qc Config - if qc, err = LoadLocalConfig(filename, &struct { + qc, err = LoadConfig(filename, clnt, &struct { Version string - }{}); err != nil { + }{}) + if err != nil { return "", err } - return qc.Version(), err + return qc.Version(), nil } -// LoadLocalConfig - loads json config from filename for the a given struct data -func LoadLocalConfig(filename string, data interface{}) (qc Config, err error) { - if qc, err = NewLocalConfig(data); err == nil { - err = qc.Load(filename) +// LoadConfig - loads json config from filename for the a given struct data +func LoadConfig(filename string, clnt etcd.Client, data interface{}) (qc Config, err error) { + qc, err = NewConfig(data, clnt) + if err != nil { + return nil, err } - return qc, err + return qc, qc.Load(filename) } -// SaveLocalConfig - saves given configuration data into given file as JSON. -func SaveLocalConfig(filename string, data interface{}) (err error) { +// SaveConfig - saves given configuration data into given file as JSON. +func SaveConfig(data interface{}, filename string, clnt etcd.Client) (err error) { + if err = checkData(data); err != nil { + return err + } var qc Config - if qc, err = NewLocalConfig(data); err == nil { - err = qc.Save(filename) + qc, err = NewConfig(data, clnt) + if err != nil { + return err } + return qc.Save(filename) +} - return err +// NewConfig loads config from etcd client if provided, otherwise loads from a local filename. +// fails when all else fails. +func NewConfig(data interface{}, clnt etcd.Client) (cfg Config, err error) { + if err := checkData(data); err != nil { + return nil, err + } + + d := new(config) + d.data = data + d.clnt = clnt + d.lock = new(sync.RWMutex) + return d, nil } diff --git a/pkg/quick/quick_etcd.go b/pkg/quick/quick_etcd.go deleted file mode 100644 index 6fb891020..000000000 --- a/pkg/quick/quick_etcd.go +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Quick - Quick key value store for config files and persistent state files - * - * Quick (C) 2018 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package quick - -import ( - "encoding/json" - "path/filepath" - "reflect" - "runtime" - "strings" - "sync" - "time" - - etcdc "github.com/coreos/etcd/client" - "github.com/fatih/structs" - "golang.org/x/net/context" -) - -// etcdConfig - implements quick.Config interface -type etcdConfig struct { - lock *sync.Mutex - data interface{} - clnt etcdc.Client -} - -// Version returns the current config file format version -func (d etcdConfig) Version() string { - st := structs.New(d.data) - f := st.Field("Version") - return f.Value().(string) -} - -// String converts JSON config to printable string -func (d etcdConfig) String() string { - configBytes, _ := json.MarshalIndent(d.data, "", "\t") - return string(configBytes) -} - -// Save writes config data to an configured etcd endpoints. Data format -// is selected based on file extension or JSON if not provided. -func (d etcdConfig) Save(filename string) error { - d.lock.Lock() - defer d.lock.Unlock() - - // Fetch filename's extension - ext := filepath.Ext(filename) - // Marshal data - dataBytes, err := toMarshaller(ext)(d.data) - if err != nil { - return err - } - if runtime.GOOS == "windows" { - dataBytes = []byte(strings.Replace(string(dataBytes), "\n", "\r\n", -1)) - } - - kapi := etcdc.NewKeysAPI(d.clnt) - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) - _, err = kapi.Update(ctx, filename, string(dataBytes)) - cancel() - return err -} - -// 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 etcdConfig) Load(filename string) error { - d.lock.Lock() - defer d.lock.Unlock() - - kapi := etcdc.NewKeysAPI(d.clnt) - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) - resp, err := kapi.Get(ctx, filename, nil) - cancel() - if err != nil { - return err - } - - var ev *etcdc.Node - switch { - case resp.Node.Dir: - for _, ev = range resp.Node.Nodes { - if string(ev.Key) == filename { - break - } - } - default: - ev = resp.Node - } - - fileData := ev.Value - if runtime.GOOS == "windows" { - fileData = strings.Replace(ev.Value, "\r\n", "\n", -1) - } - - // Unmarshal file's content - return toUnmarshaller(filepath.Ext(filename))([]byte(fileData), d.data) -} - -// Data - grab internal data map for reading -func (d etcdConfig) Data() interface{} { - return d.data -} - -//Diff - list fields that are in A but not in B -func (d etcdConfig) Diff(c Config) ([]structs.Field, error) { - var fields []structs.Field - - currFields := structs.Fields(d.Data()) - newFields := structs.Fields(c.Data()) - - var found bool - for _, currField := range currFields { - found = false - for _, newField := range newFields { - if reflect.DeepEqual(currField.Name(), newField.Name()) { - found = true - } - } - if !found { - fields = append(fields, *currField) - } - } - return fields, nil -} - -// DeepDiff - list fields in A that are missing or not equal to fields in B -func (d etcdConfig) DeepDiff(c Config) ([]structs.Field, error) { - var fields []structs.Field - - currFields := structs.Fields(d.Data()) - newFields := structs.Fields(c.Data()) - - var found bool - for _, currField := range currFields { - found = false - for _, newField := range newFields { - if reflect.DeepEqual(currField.Value(), newField.Value()) { - found = true - } - } - if !found { - fields = append(fields, *currField) - } - } - return fields, nil -} - -// NewEtcdConfig - instantiate a new etcd config -func NewEtcdConfig(data interface{}, clnt etcdc.Client) (Config, error) { - if err := checkData(data); err != nil { - return nil, err - } - - d := new(etcdConfig) - d.data = data - d.clnt = clnt - d.lock = &sync.Mutex{} - return d, nil -} - -// GetEtcdVersion - extracts the version information. -func GetEtcdVersion(filename string, clnt etcdc.Client) (version string, err error) { - var qc Config - if qc, err = LoadEtcdConfig(filename, &struct { - Version string - }{}, clnt); err != nil { - return "", err - } - return qc.Version(), err -} - -// LoadEtcdConfig - loads json config from etcd backend for the given struct data -func LoadEtcdConfig(filename string, data interface{}, clnt etcdc.Client) (qc Config, err error) { - if qc, err = NewEtcdConfig(data, clnt); err == nil { - err = qc.Load(filename) - } - return qc, err -} - -// SaveEtcdConfig - saves given configuration data into etcd backend. -func SaveEtcdConfig(filename string, data interface{}, clnt etcdc.Client) (err error) { - var qc Config - if qc, err = NewEtcdConfig(data, clnt); err == nil { - err = qc.Save(filename) - } - - return err -} diff --git a/pkg/quick/quick_test.go b/pkg/quick/quick_test.go index 82e3c8ee5..d63191d1f 100644 --- a/pkg/quick/quick_test.go +++ b/pkg/quick/quick_test.go @@ -36,7 +36,7 @@ func TestReadVersion(t *testing.T) { Version string } saveMe := myStruct{"1"} - config, err := NewLocalConfig(&saveMe) + config, err := NewConfig(&saveMe, nil) if err != nil { t.Fatal(err) } @@ -45,7 +45,7 @@ func TestReadVersion(t *testing.T) { t.Fatal(err) } - version, err := GetLocalVersion("test.json") + version, err := GetVersion("test.json", nil) if err != nil { t.Fatal(err) } @@ -59,7 +59,7 @@ func TestReadVersionErr(t *testing.T) { Version int } saveMe := myStruct{1} - _, err := NewLocalConfig(&saveMe) + _, err := NewConfig(&saveMe, nil) if err == nil { t.Fatal("Unexpected should fail in initialization for bad input") } @@ -69,7 +69,7 @@ func TestReadVersionErr(t *testing.T) { t.Fatal(err) } - _, err = GetLocalVersion("test.json") + _, err = GetVersion("test.json", nil) if err == nil { t.Fatal("Unexpected should fail to fetch version") } @@ -79,7 +79,7 @@ func TestReadVersionErr(t *testing.T) { t.Fatal(err) } - _, err = GetLocalVersion("test.json") + _, err = GetVersion("test.json", nil) if err == nil { t.Fatal("Unexpected should fail to fetch version") } @@ -95,7 +95,7 @@ func TestSaveFailOnDir(t *testing.T) { Version string } saveMe := myStruct{"1"} - config, err := NewLocalConfig(&saveMe) + config, err := NewConfig(&saveMe, nil) if err != nil { t.Fatal(err) } @@ -155,7 +155,7 @@ func TestLoadFile(t *testing.T) { Directories []string } saveMe := myStruct{} - _, err := LoadLocalConfig("test.json", &saveMe) + _, err := LoadConfig("test.json", nil, &saveMe) if err == nil { t.Fatal(err) } @@ -167,11 +167,11 @@ func TestLoadFile(t *testing.T) { if err = file.Close(); err != nil { t.Fatal(err) } - _, err = LoadLocalConfig("test.json", &saveMe) + _, err = LoadConfig("test.json", nil, &saveMe) if err == nil { t.Fatal("Unexpected should fail to load empty JSON") } - config, err := NewLocalConfig(&saveMe) + config, err := NewConfig(&saveMe, nil) if err != nil { t.Fatal(err) } @@ -186,7 +186,7 @@ func TestLoadFile(t *testing.T) { } saveMe = myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err = NewLocalConfig(&saveMe) + config, err = NewConfig(&saveMe, nil) if err != nil { t.Fatal(err) } @@ -195,7 +195,7 @@ func TestLoadFile(t *testing.T) { t.Fatal(err) } saveMe1 := myStruct{} - _, err = LoadLocalConfig("test.json", &saveMe1) + _, err = LoadConfig("test.json", nil, &saveMe1) if err != nil { t.Fatal(err) } @@ -240,7 +240,7 @@ directories: saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} // Save format using - config, err := NewLocalConfig(&saveMe) + config, err := NewConfig(&saveMe, nil) if err != nil { t.Fatal(err) } @@ -262,7 +262,7 @@ directories: // Check if the loaded data is the same as the saved one loadMe := myStruct{} - config, err = NewLocalConfig(&loadMe) + config, err = NewConfig(&loadMe, nil) if err != nil { t.Fatal(err) } @@ -306,7 +306,7 @@ func TestJSONFormat(t *testing.T) { saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} // Save format using - config, err := NewLocalConfig(&saveMe) + config, err := NewConfig(&saveMe, nil) if err != nil { t.Fatal(err) } @@ -328,7 +328,7 @@ func TestJSONFormat(t *testing.T) { // Check if the loaded data is the same as the saved one loadMe := myStruct{} - config, err = NewLocalConfig(&loadMe) + config, err = NewConfig(&loadMe, nil) if err != nil { t.Fatal(err) } @@ -351,7 +351,7 @@ func TestSaveLoad(t *testing.T) { Directories []string } saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err := NewLocalConfig(&saveMe) + config, err := NewConfig(&saveMe, nil) if err != nil { t.Fatal(err) } @@ -361,7 +361,7 @@ func TestSaveLoad(t *testing.T) { } loadMe := myStruct{Version: "1"} - newConfig, err := NewLocalConfig(&loadMe) + newConfig, err := NewConfig(&loadMe, nil) if err != nil { t.Fatal(err) } @@ -393,7 +393,7 @@ func TestSaveBackup(t *testing.T) { Directories []string } saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err := NewLocalConfig(&saveMe) + config, err := NewConfig(&saveMe, nil) if err != nil { t.Fatal(err) } @@ -403,7 +403,7 @@ func TestSaveBackup(t *testing.T) { } loadMe := myStruct{Version: "1"} - newConfig, err := NewLocalConfig(&loadMe) + newConfig, err := NewConfig(&loadMe, nil) if err != nil { t.Fatal(err) } @@ -424,7 +424,7 @@ func TestSaveBackup(t *testing.T) { t.Fatal("Expected to mismatch but succeeded instead") } - config, err = NewLocalConfig(&mismatch) + config, err = NewConfig(&mismatch, nil) if err != nil { t.Fatal(err) } @@ -442,20 +442,20 @@ func TestDiff(t *testing.T) { Directories []string } saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err := NewLocalConfig(&saveMe) + config, err := NewConfig(&saveMe, nil) if err != nil { t.Fatal(err) } - type myNewLocalConfigStruct struct { + type myNewConfigStruct struct { Version string // User string Password string Directories []string } - mismatch := myNewLocalConfigStruct{"1", "nopassword", []string{"Work", "documents", "Music"}} - newConfig, err := NewLocalConfig(&mismatch) + mismatch := myNewConfigStruct{"1", "nopassword", []string{"Work", "documents", "Music"}} + newConfig, err := NewConfig(&mismatch, nil) if err != nil { t.Fatal(err) } @@ -482,13 +482,13 @@ func TestDeepDiff(t *testing.T) { Directories []string } saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} - config, err := NewLocalConfig(&saveMe) + config, err := NewConfig(&saveMe, nil) if err != nil { t.Fatal(err) } mismatch := myStruct{"1", "Guest", "nopassword", []string{"Work", "documents", "Music"}} - newConfig, err := NewLocalConfig(&mismatch) + newConfig, err := NewConfig(&mismatch, nil) if err != nil { t.Fatal(err) }