Esempio n. 1
0
func (s *MySuite) TestDeepDiff(c *C) {
	type myStruct struct {
		Version  string
		User     string
		Password string
		Folders  []string
	}
	saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}}
	config, err := quick.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)
	c.Assert(err, IsNil)
	c.Assert(newConfig, Not(IsNil))

	fields, err := config.DeepDiff(newConfig)
	c.Assert(err, IsNil)
	c.Assert(len(fields), Equals, 2)

	// Uncomment for debugging
	//	for i, field := range fields {
	//		fmt.Printf("DeepDiff[%d]: %s=%v\n", i, field.Name(), field.Value())
	//	}
}
Esempio n. 2
0
// removeAlias - remove alias
func removeAlias(alias string) {
	if alias == "" {
		fatalIf(errDummy().Trace(), "Alias or URL cannot be empty.")
	}
	conf := newConfigV2()
	config, err := quick.New(conf)
	fatalIf(err.Trace(conf.Version), "Failed to initialize ‘quick’ configuration data structure.")

	err = config.Load(mustGetMcConfigPath())
	fatalIf(err.Trace(), "Unable to load config path")
	if isAliasReserved(alias) {
		fatalIf(errDummy().Trace(), fmt.Sprintf("Cannot use a reserved name ‘%s’ as an alias. Following are reserved names: [help, private, readonly, public, authenticated].", alias))
	}
	if !isValidAliasName(alias) {
		fatalIf(errDummy().Trace(), fmt.Sprintf("Alias name ‘%s’ is invalid, valid examples are: mybucket, Area51, Grand-Nagus", alias))
	}
	// convert interface{} back to its original struct
	newConf := config.Data().(*configV2)

	if _, ok := newConf.Aliases[alias]; !ok {
		fatalIf(errDummy().Trace(), fmt.Sprintf("Alias ‘%s’ does not exist.", alias))
	}
	delete(newConf.Aliases, alias)

	newConfig, err := quick.New(newConf)
	fatalIf(err.Trace(conf.Version), "Failed to initialize ‘quick’ configuration data structure.")

	err = writeConfig(newConfig)
	fatalIf(err.Trace(alias), "Unable to save alias ‘"+alias+"’.")

	console.Println(AliasMessage{
		op:    "remove",
		Alias: alias,
	})
}
Esempio n. 3
0
func (s *MySuite) TestSaveLoad(c *C) {
	defer os.RemoveAll("test.json")
	type myStruct struct {
		Version  string
		User     string
		Password string
		Folders  []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)

	loadMe := myStruct{Version: "1"}
	newConfig, err := quick.New(&loadMe)
	c.Assert(err, IsNil)
	c.Assert(newConfig, Not(IsNil))
	err = newConfig.Load("test.json")
	c.Assert(err, IsNil)

	c.Assert(config.Data(), DeepEquals, newConfig.Data())
	c.Assert(config.Data(), DeepEquals, &loadMe)

	mismatch := myStruct{"1.1", "guest", "nopassword", []string{"Work", "Documents", "Music"}}
	c.Assert(newConfig.Data(), Not(DeepEquals), &mismatch)
}
Esempio n. 4
0
// removeAlias - remove alias
func removeAlias(alias string) {
	if strings.TrimSpace(alias) == "" {
		fatalIf(errDummy().Trace(), "Alias or URL cannot be empty.")
	}
	config, err := newConfig()
	fatalIf(err.Trace(), "Failed to initialize ‘quick’ configuration data structure.")

	configPath := mustGetMcConfigPath()
	err = config.Load(configPath)
	fatalIf(err.Trace(configPath), "Unable to load config path")
	if !isValidAliasName(alias) {
		fatalIf(errDummy().Trace(), fmt.Sprintf("Alias name ‘%s’ is invalid, valid examples are: mybucket, Area51, Grand-Nagus", alias))
	}

	// convert interface{} back to its original struct
	newConf := config.Data().(*configV5)
	if _, ok := newConf.Aliases[alias]; !ok {
		fatalIf(errDummy().Trace(), fmt.Sprintf("Alias ‘%s’ does not exist.", alias))
	}
	delete(newConf.Aliases, alias)

	newConfig, err := quick.New(newConf)
	fatalIf(err.Trace(globalMCConfigVersion), "Failed to initialize ‘quick’ configuration data structure.")
	err = writeConfig(newConfig)
	fatalIf(err.Trace(alias), "Unable to save alias ‘"+alias+"’.")

	Prints("%s\n", AliasMessage{
		op:    "remove",
		Alias: alias,
	})
}
Esempio n. 5
0
// Migrate config version ‘4’ to ‘5’. Rename hostConfigV4.Signature  -> hostConfigV5.API.
func migrateConfigV4ToV5() {
	if !isMcConfigExists() {
		return
	}
	mcCfgV4, e := quick.Load(mustGetMcConfigPath(), newConfigV4())
	fatalIf(probe.NewError(e), "Unable to load mc config V4.")

	// update to newer version
	if mcCfgV4.Version() != "4" {
		return
	}

	cfgV5 := newConfigV5()
	for k, v := range mcCfgV4.Data().(*configV4).Aliases {
		cfgV5.Aliases[k] = v
	}
	for host, hostCfgV4 := range mcCfgV4.Data().(*configV4).Hosts {
		cfgV5.Hosts[host] = hostConfigV5{
			AccessKeyID:     hostCfgV4.AccessKeyID,
			SecretAccessKey: hostCfgV4.SecretAccessKey,
			API:             "v4", // Rename from .Signature to .API
		}
	}

	mcNewCfgV5, e := quick.New(cfgV5)
	fatalIf(probe.NewError(e), "Unable to initialize quick config for config version ‘5’.")

	e = mcNewCfgV5.Save(mustGetMcConfigPath())
	fatalIf(probe.NewError(e), "Unable to save config version ‘5’.")

	console.Infof("Successfully migrated %s from version ‘4’ to version ‘5’.\n", mustGetMcConfigPath())
}
Esempio n. 6
0
// Migrate from config ‘1.0.1’ to ‘2’. Drop semantic versioning and move to integer versioning. No other changes.
func migrateConfigV101ToV2() {
	if !isMcConfigExists() {
		return
	}
	mcCfgV101, e := quick.Load(mustGetMcConfigPath(), newConfigV101())
	fatalIf(probe.NewError(e), "Unable to load config version ‘1.0.1’.")

	// update to newer version
	if mcCfgV101.Version() != "1.0.1" {
		return
	}

	cfgV2 := newConfigV2()

	// Copy aliases.
	for k, v := range mcCfgV101.Data().(*configV101).Aliases {
		cfgV2.Aliases[k] = v
	}

	// Copy hosts.
	for k, hostCfgV101 := range mcCfgV101.Data().(*configV101).Hosts {
		cfgV2.Hosts[k] = hostConfigV2{
			AccessKeyID:     hostCfgV101.AccessKeyID,
			SecretAccessKey: hostCfgV101.SecretAccessKey,
		}
	}

	mcCfgV2, e := quick.New(cfgV2)
	fatalIf(probe.NewError(e), "Unable to initialize quick config for config version ‘2’.")

	e = mcCfgV2.Save(mustGetMcConfigPath())
	fatalIf(probe.NewError(e), "Unable to save config version ‘2’.")

	console.Infof("Successfully migrated %s from version ‘1.0.1’ to version ‘2’.\n", mustGetMcConfigPath())
}
Esempio n. 7
0
func loadSessionV6Header(sid string) (*sessionV6Header, *probe.Error) {
	if !isSessionDirExists() {
		return nil, errInvalidArgument().Trace()
	}

	sessionFile, err := getSessionFile(sid)
	if err != nil {
		return nil, err.Trace(sid)
	}

	if _, e := os.Stat(sessionFile); e != nil {
		return nil, probe.NewError(e)
	}

	sV6Header := &sessionV6Header{}
	sV6Header.Version = "6"
	qs, e := quick.New(sV6Header)
	if e != nil {
		return nil, probe.NewError(e).Trace(sid, sV6Header.Version)
	}
	e = qs.Load(sessionFile)
	if e != nil {
		return nil, probe.NewError(e).Trace(sid, sV6Header.Version)
	}

	sV6Header = qs.Data().(*sessionV6Header)
	return sV6Header, nil
}
Esempio n. 8
0
func removeHost(hostGlob string) {
	if strings.TrimSpace(hostGlob) == "" {
		fatalIf(errDummy().Trace(), "Alias or URL cannot be empty.")
	}
	if strings.TrimSpace(hostGlob) == "dl.minio.io:9000" {
		fatalIf(errDummy().Trace(), "‘"+hostGlob+"’ is reserved hostname and cannot be removed.")
	}
	config, err := newConfig()
	fatalIf(err.Trace(globalMCConfigVersion), "Failed to initialize ‘quick’ configuration data structure.")

	configPath := mustGetMcConfigPath()
	err = config.Load(configPath)
	fatalIf(err.Trace(configPath), "Unable to load config path")

	// convert interface{} back to its original struct
	newConf := config.Data().(*configV5)
	if _, ok := newConf.Hosts[hostGlob]; !ok {
		fatalIf(errDummy().Trace(), fmt.Sprintf("Host glob ‘%s’ does not exist.", hostGlob))
	}
	delete(newConf.Hosts, hostGlob)

	newConfig, err := quick.New(newConf)
	fatalIf(err.Trace(globalMCConfigVersion), "Failed to initialize ‘quick’ configuration data structure.")
	err = writeConfig(newConfig)
	fatalIf(err.Trace(hostGlob), "Unable to save host glob ‘"+hostGlob+"’.")

	Prints("%s\n", HostMessage{
		op:   "remove",
		Host: hostGlob,
	})
}
Esempio n. 9
0
// Load shareDB entries from disk. Any entries held in memory are reset.
func (s *shareDBV1) Load(filename string) *probe.Error {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	// Check if the db file exist.
	if _, e := os.Stat(filename); e != nil {
		return probe.NewError(e)
	}

	// Initialize and load using quick package.
	qs, e := quick.New(newShareDBV1())
	if e != nil {
		return probe.NewError(e).Trace(filename)
	}
	e = qs.Load(filename)
	if e != nil {
		return probe.NewError(e).Trace(filename)
	}

	// Copy map over.
	for k, v := range qs.Data().(*shareDBV1).Shares {
		s.Shares[k] = v
	}

	// Filter out expired entries and save changes back to disk.
	s.deleteAllExpired()
	s.save(filename)

	return nil
}
Esempio n. 10
0
// addAlias - add new aliases
func addAlias(alias, url string) {
	if alias == "" || url == "" {
		fatalIf(errDummy().Trace(), "Alias or URL cannot be empty.")
	}
	config, err := newConfig()
	fatalIf(err.Trace(globalMCConfigVersion), "Failed to initialize ‘quick’ configuration data structure.")

	err = config.Load(mustGetMcConfigPath())
	fatalIf(err.Trace(), "Unable to load config path")

	url = strings.TrimSuffix(url, "/")
	if !strings.HasPrefix(url, "http") {
		fatalIf(errDummy().Trace(), fmt.Sprintf("Invalid alias URL ‘%s’. Valid examples are: http://s3.amazonaws.com, https://yourbucket.example.com.", url))
	}
	if !isValidAliasName(alias) {
		fatalIf(errDummy().Trace(), fmt.Sprintf("Alias name ‘%s’ is invalid, valid examples are: mybucket, Area51, Grand-Nagus", alias))
	}
	// convert interface{} back to its original struct
	newConf := config.Data().(*configV5)
	if oldURL, ok := newConf.Aliases[alias]; ok {
		fatalIf(errDummy().Trace(), fmt.Sprintf("Alias ‘%s’ already exists for ‘%s’.", alias, oldURL))
	}
	newConf.Aliases[alias] = url
	newConfig, err := quick.New(newConf)
	fatalIf(err.Trace(globalMCConfigVersion), "Failed to initialize ‘quick’ configuration data structure.")

	err = writeConfig(newConfig)
	fatalIf(err.Trace(alias, url), "Unable to save alias ‘"+alias+"’.")

	Prints("%s\n", AliasMessage{
		op:    "add",
		Alias: alias,
		URL:   url,
	})
}
Esempio n. 11
0
// getMcConfig - reads configuration file and returns config
func getMcConfig() (*configV2, *probe.Error) {
	if !isMcConfigExists() {
		return nil, errInvalidArgument().Trace()
	}

	configFile, err := getMcConfigPath()
	if err != nil {
		return nil, err.Trace()
	}

	// Cached in private global variable.
	if v := cache.Get(); v != nil { // Use previously cached config.
		return v.(quick.Config).Data().(*configV2), nil
	}

	conf := newConfigV2()
	qconf, err := quick.New(conf)
	if err != nil {
		return nil, err.Trace()
	}

	err = qconf.Load(configFile)
	if err != nil {
		return nil, err.Trace()
	}
	cache.Put(qconf)
	return qconf.Data().(*configV2), nil

}
Esempio n. 12
0
// Version '3' to '4' migrates config, removes previous fields related
// to backend types and server address. This change further simplifies
// the config for future additions.
func migrateV3ToV4() {
	cv3, err := loadConfigV3()
	if err != nil && os.IsNotExist(err) {
		return
	}
	fatalIf(err, "Unable to load config version ‘3’.")
	if cv3.Version != "3" {
		return
	}

	// Save only the new fields, ignore the rest.
	srvConfig := &configV4{}
	srvConfig.Version = "4"
	srvConfig.Credential = cv3.Credential
	srvConfig.Region = cv3.Region
	if srvConfig.Region == "" {
		// Region needs to be set for AWS Signature Version 4.
		srvConfig.Region = "us-east-1"
	}
	srvConfig.Logger.Console = cv3.Logger.Console
	srvConfig.Logger.File = cv3.Logger.File
	srvConfig.Logger.Syslog = cv3.Logger.Syslog

	qc, err := quick.New(srvConfig)
	fatalIf(err, "Unable to initialize the quick config.")
	configFile, err := getConfigFile()
	fatalIf(err, "Unable to get config file.")

	err = qc.Save(configFile)
	fatalIf(err, "Failed to migrate config from ‘"+cv3.Version+"’ to ‘"+srvConfig.Version+"’ failed.")

	console.Println("Migration from version ‘" + cv3.Version + "’ to ‘" + srvConfig.Version + "’ completed successfully.")
}
Esempio n. 13
0
// loadSession - reads session file if exists and re-initiates internal variables
func loadSessionV1(sid string) (*sessionV1, *probe.Error) {
	if !isSessionDirExists() {
		return nil, probe.NewError(errors.New("Session folder does not exist."))
	}

	sessionFile, err := getSessionFileV1(sid)
	if err != nil {
		return nil, err.Trace(sid)
	}

	s := new(sessionV1)
	s.Version = "1.0.0"
	// map of command and files copied
	s.URLs = nil
	s.Lock = new(sync.Mutex)
	s.Files = make(map[string]bool)
	qs, err := quick.New(s)
	if err != nil {
		return nil, err.Trace(s.Version)
	}
	err = qs.Load(sessionFile)
	if err != nil {
		return nil, err.Trace(sessionFile, s.Version)
	}
	return qs.Data().(*sessionV1), nil
}
Esempio n. 14
0
// IsModified - returns if in memory session header has changed from
// its on disk value.
func (s *sessionV8) isModified(sessionFile string) (bool, *probe.Error) {
	qs, e := quick.New(s.Header)
	if e != nil {
		return false, probe.NewError(e).Trace(s.SessionID)
	}

	var currentHeader = &sessionV8Header{}
	currentQS, e := quick.Load(sessionFile, currentHeader)
	if e != nil {
		// If session does not exist for the first, return modified to
		// be true.
		if os.IsNotExist(e) {
			return true, nil
		}
		// For all other errors return.
		return false, probe.NewError(e).Trace(s.SessionID)
	}

	changedFields, e := qs.DeepDiff(currentQS)
	if e != nil {
		return false, probe.NewError(e).Trace(s.SessionID)
	}

	// Returns true if there are changed entries.
	return len(changedFields) > 0, nil
}
Esempio n. 15
0
func (s *MySuite) TestVersion(c *C) {
	defer os.RemoveAll("test.json")
	type myStruct struct {
		Version  string
		User     string
		Password string
		Folders  []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))
}
Esempio n. 16
0
// save - wrapper for quick.Save and saves only if sessionHeader is
// modified.
func (s *sessionV8) save() *probe.Error {
	sessionFile, err := getSessionFile(s.SessionID)
	if err != nil {
		return err.Trace(s.SessionID)
	}

	// Verify if sessionFile is modified.
	modified, err := s.isModified(sessionFile)
	if err != nil {
		return err.Trace(s.SessionID)
	}
	// Header is modified, we save it.
	if modified {
		qs, e := quick.New(s.Header)
		if e != nil {
			return probe.NewError(e).Trace(s.SessionID)
		}
		// Save an return.
		e = qs.Save(sessionFile)
		if e != nil {
			return probe.NewError(e).Trace(sessionFile)
		}
	}
	return nil
}
Esempio n. 17
0
// Version '6' to '7' migrates config, removes previous fields related
// 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
		}
		return fmt.Errorf("Unable to load config version ‘6’. %v", err)
	}
	if cv6.Version != "6" {
		return nil
	}

	// Save only the new fields, ignore the rest.
	srvConfig := &serverConfigV7{}
	srvConfig.Version = "7"
	srvConfig.Credential = cv6.Credential
	srvConfig.Region = cv6.Region
	if srvConfig.Region == "" {
		// Region needs to be set for AWS Signature Version 4.
		srvConfig.Region = "us-east-1"
	}
	srvConfig.Logger.Console = cv6.Logger.Console
	srvConfig.Logger.File = cv6.Logger.File
	srvConfig.Logger.Syslog = cv6.Logger.Syslog
	srvConfig.Notify.AMQP = make(map[string]amqpNotify)
	srvConfig.Notify.ElasticSearch = make(map[string]elasticSearchNotify)
	srvConfig.Notify.Redis = make(map[string]redisNotify)
	if len(cv6.Notify.AMQP) == 0 {
		srvConfig.Notify.AMQP["1"] = amqpNotify{}
	} else {
		srvConfig.Notify.AMQP = cv6.Notify.AMQP
	}
	if len(cv6.Notify.ElasticSearch) == 0 {
		srvConfig.Notify.ElasticSearch["1"] = elasticSearchNotify{}
	} else {
		srvConfig.Notify.ElasticSearch = cv6.Notify.ElasticSearch
	}
	if len(cv6.Notify.Redis) == 0 {
		srvConfig.Notify.Redis["1"] = redisNotify{}
	} else {
		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)
	}
	configFile, err := getConfigFile()
	if err != nil {
		return fmt.Errorf("Unable to get config file. %v", err)
	}

	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.")
	return nil
}
Esempio n. 18
0
// Save this session.
func (s *sessionV8) Save() *probe.Error {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	if s.DataFP.dirty {
		if err := s.DataFP.Sync(); err != nil {
			return probe.NewError(err)
		}
		s.DataFP.dirty = false
	}

	qs, e := quick.New(s.Header)
	if e != nil {
		return probe.NewError(e).Trace(s.SessionID)
	}

	sessionFile, err := getSessionFile(s.SessionID)
	if err != nil {
		return err.Trace(s.SessionID)
	}
	e = qs.Save(sessionFile)
	if e != nil {
		return probe.NewError(e).Trace(sessionFile)
	}
	return nil
}
Esempio n. 19
0
// initConfig - initialize server config. config version (called only once).
func initConfig() error {
	if !isConfigFileExists() {
		// Initialize server config.
		srvCfg := &serverConfigV7{}
		srvCfg.Version = globalMinioConfigVersion
		srvCfg.Region = "us-east-1"
		srvCfg.Credential = mustGenAccessKeys()

		// Enable console logger by default on a fresh run.
		srvCfg.Logger.Console = consoleLogger{
			Enable: true,
			Level:  "fatal",
		}

		// Make sure to initialize notification configs.
		srvCfg.Notify.AMQP = make(map[string]amqpNotify)
		srvCfg.Notify.AMQP["1"] = amqpNotify{}
		srvCfg.Notify.ElasticSearch = make(map[string]elasticSearchNotify)
		srvCfg.Notify.ElasticSearch["1"] = elasticSearchNotify{}
		srvCfg.Notify.Redis = make(map[string]redisNotify)
		srvCfg.Notify.Redis["1"] = redisNotify{}
		srvCfg.rwMutex = &sync.RWMutex{}

		// Create config path.
		err := createConfigPath()
		if err != nil {
			return err
		}

		// Save the new config globally.
		serverConfig = srvCfg

		// Save config into file.
		return serverConfig.Save()
	}
	configFile, err := getConfigFile()
	if err != nil {
		return err
	}
	if _, err = os.Stat(configFile); err != nil {
		return err
	}
	srvCfg := &serverConfigV7{}
	srvCfg.Version = globalMinioConfigVersion
	srvCfg.rwMutex = &sync.RWMutex{}
	qc, err := quick.New(srvCfg)
	if err != nil {
		return err
	}
	if err := qc.Load(configFile); err != nil {
		return err
	}
	// Save the loaded config globally.
	serverConfig = srvCfg
	// Set the version properly after the unmarshalled json is loaded.
	serverConfig.Version = globalMinioConfigVersion

	return nil
}
Esempio n. 20
0
// newConfig - get new config interface
func newConfig() (config quick.Config, err *probe.Error) {
	conf := newConfigV2()
	config, err = quick.New(conf)
	if err != nil {
		return nil, err.Trace()
	}
	return config, nil
}
Esempio n. 21
0
// saveBucketsMetadata - save metadata of all buckets
func saveBucketsMetadata(buckets Buckets) *probe.Error {
	qc, err := quick.New(buckets)
	if err != nil {
		return err.Trace()
	}
	if err := qc.Save(bucketsMetadataPath); err != nil {
		return err.Trace()
	}
	return nil
}
Esempio n. 22
0
// saveMultipartsSession - save multiparts
func saveMultipartsSession(multiparts Multiparts) *probe.Error {
	qc, err := quick.New(multiparts)
	if err != nil {
		return err.Trace()
	}
	if err := qc.Save(multipartsMetadataPath); err != nil {
		return err.Trace()
	}
	return nil
}
Esempio n. 23
0
func (s *CmdTestSuite) TestNewConfigV2(c *C) {
	root, err := ioutil.TempDir(os.TempDir(), "mc-")
	c.Assert(err, IsNil)
	defer os.RemoveAll(root)

	conf, perr := newConfig()
	c.Assert(perr, IsNil)
	configFile := filepath.Join(root, "config.json")
	perr = conf.Save(configFile)
	c.Assert(perr, IsNil)

	confNew := newConfigV2()
	config, perr := quick.New(confNew)
	c.Assert(perr, IsNil)
	perr = config.Load(configFile)
	c.Assert(perr, IsNil)
	data := config.Data().(*configV2)

	type aliases struct {
		name string
		url  string
	}

	wantAliases := []aliases{
		{
			"s3",
			"https://s3.amazonaws.com",
		},
		{
			"play",
			"https://play.minio.io:9000",
		},
		{
			"localhost",
			"http://localhost:9000",
		},
	}
	for _, alias := range wantAliases {
		url, ok := data.Aliases[alias.name]
		c.Assert(ok, Equals, true)
		c.Assert(url, Equals, alias.url)
	}

	wantHosts := []string{
		"localhost:*",
		"127.0.0.1:*",
		"play.minio.io:9000",
		"dl.minio.io:9000",
		"s3*.amazonaws.com",
	}
	for _, host := range wantHosts {
		_, ok := data.Hosts[host]
		c.Assert(ok, Equals, true)
	}
}
Esempio n. 24
0
// Migrate from config version 1.0 to 1.0.1. Populate example entries and save it back.
func migrateConfigV1ToV101() {
	if !isMcConfigExists() {
		return
	}
	mcCfgV1, e := quick.Load(mustGetMcConfigPath(), newConfigV1())
	fatalIf(probe.NewError(e), "Unable to load config version ‘1’.")

	// If loaded config version does not match 1.0.0, we do nothing.
	if mcCfgV1.Version() != "1.0.0" {
		return
	}

	// 1.0.1 is compatible to 1.0.0. We are just adding new entries.
	cfgV101 := newConfigV101()

	// Copy aliases.
	for k, v := range mcCfgV1.Data().(*configV1).Aliases {
		cfgV101.Aliases[k] = v
	}

	// Copy hosts.
	for k, hostCfgV1 := range mcCfgV1.Data().(*configV1).Hosts {
		cfgV101.Hosts[k] = hostConfigV101{
			AccessKeyID:     hostCfgV1.AccessKeyID,
			SecretAccessKey: hostCfgV1.SecretAccessKey,
		}
	}

	// Example localhost entry.
	if _, ok := cfgV101.Hosts["localhost:*"]; !ok {
		cfgV101.Hosts["localhost:*"] = hostConfigV101{}
	}

	// Example loopback IP entry.
	if _, ok := cfgV101.Hosts["127.0.0.1:*"]; !ok {
		cfgV101.Hosts["127.0.0.1:*"] = hostConfigV101{}
	}

	// Example AWS entry.
	// Look for glob string (not glob match). We used to support glob based key matching earlier.
	if _, ok := cfgV101.Hosts["*.s3*.amazonaws.com"]; !ok {
		cfgV101.Hosts["*.s3*.amazonaws.com"] = hostConfigV101{
			AccessKeyID:     "YOUR-ACCESS-KEY-ID-HERE",
			SecretAccessKey: "YOUR-SECRET-ACCESS-KEY-HERE",
		}
	}

	// Save the new config back to the disk.
	mcCfgV101, e := quick.New(cfgV101)
	fatalIf(probe.NewError(e), "Unable to initialize quick config for config version ‘1.0.1’.")
	e = mcCfgV101.Save(mustGetMcConfigPath())
	fatalIf(probe.NewError(e), "Unable to save config version ‘1.0.1’.")

	console.Infof("Successfully migrated %s from version ‘1.0.0’ to version ‘1.0.1’.\n", mustGetMcConfigPath())
}
Esempio n. 25
0
func saveSharedURLsV2(s *sharedURLsV2) *probe.Error {
	qs, err := quick.New(s)
	if err != nil {
		return err.Trace()
	}
	sharedURLsDataFile, err := getSharedURLsDataFile()
	if err != nil {
		return err.Trace()
	}
	return qs.Save(sharedURLsDataFile).Trace(sharedURLsDataFile)
}
Esempio n. 26
0
// Persist share uploads to disk.
func (s shareDBV1) save(filename string) *probe.Error {
	// Initialize a new quick file.
	qs, e := quick.New(s)
	if e != nil {
		return probe.NewError(e).Trace(filename)
	}
	if e := qs.Save(filename); e != nil {
		return probe.NewError(e).Trace(filename)
	}
	return nil
}
Esempio n. 27
0
// initConfig - initialize server config. config version (called only once).
func initConfig() error {
	if !isConfigFileExists() {
		srvCfg := &serverConfigV4{}
		srvCfg.Version = globalMinioConfigVersion
		srvCfg.Region = "us-east-1"
		srvCfg.Credential = mustGenAccessKeys()
		// Enable console logger by default on a fresh run.
		srvCfg.Logger.Console = consoleLogger{
			Enable: true,
			Level:  "fatal",
		}
		srvCfg.rwMutex = &sync.RWMutex{}
		// Create config path.
		err := createConfigPath()
		if err != nil {
			return err
		}

		// Create certs path.
		err = createCertsPath()
		if err != nil {
			return err
		}

		// Save the new config globally.
		serverConfig = srvCfg

		// Save config into file.
		return serverConfig.Save()
	}
	configFile, err := getConfigFile()
	if err != nil {
		return err
	}
	if _, err = os.Stat(configFile); err != nil {
		return err
	}
	srvCfg := &serverConfigV4{}
	srvCfg.Version = globalMinioConfigVersion
	srvCfg.rwMutex = &sync.RWMutex{}
	qc, err := quick.New(srvCfg)
	if err != nil {
		return err
	}
	if err := qc.Load(configFile); err != nil {
		return err
	}
	// Save the loaded config globally.
	serverConfig = srvCfg
	// Set the version properly after the unmarshalled json is loaded.
	serverConfig.Version = globalMinioConfigVersion
	return nil
}
Esempio n. 28
0
// Version '2' to '3' config migration adds new fields and re-orders
// previous fields. Simplifies config for future additions.
func migrateV2ToV3() {
	cv2, err := loadConfigV2()
	if err != nil && os.IsNotExist(err) {
		return
	}
	fatalIf(err, "Unable to load config version ‘2’.")
	if cv2.Version != "2" {
		return
	}
	srvConfig := &configV3{}
	srvConfig.Version = "3"
	srvConfig.Addr = ":9000"
	srvConfig.Credential = credential{
		AccessKeyID:     cv2.Credentials.AccessKeyID,
		SecretAccessKey: cv2.Credentials.SecretAccessKey,
	}
	srvConfig.Region = cv2.Credentials.Region
	if srvConfig.Region == "" {
		// Region needs to be set for AWS Signature V4.
		srvConfig.Region = "us-east-1"
	}
	srvConfig.Logger.Console = consoleLogger{
		Enable: true,
		Level:  "fatal",
	}
	flogger := fileLogger{}
	flogger.Level = "error"
	if cv2.FileLogger.Filename != "" {
		flogger.Enable = true
		flogger.Filename = cv2.FileLogger.Filename
	}
	srvConfig.Logger.File = flogger

	slogger := syslogLogger{}
	slogger.Level = "debug"
	if cv2.SyslogLogger.Addr != "" {
		slogger.Enable = true
		slogger.Addr = cv2.SyslogLogger.Addr
	}
	srvConfig.Logger.Syslog = slogger

	qc, err := quick.New(srvConfig)
	fatalIf(err, "Unable to initialize config.")

	configFile, err := getConfigFile()
	fatalIf(err, "Unable to get config file.")

	// Migrate the config.
	err = qc.Save(configFile)
	fatalIf(err, "Failed to migrate config from ‘"+cv2.Version+"’ to ‘"+srvConfig.Version+"’ failed.")

	console.Println("Migration from version ‘" + cv2.Version + "’ to ‘" + srvConfig.Version + "’ completed successfully.")
}
Esempio n. 29
0
// If the host key does not have http(s), fix it.
func fixConfigV6ForHosts() {
	if !isMcConfigExists() {
		return
	}

	brokenMcCfgV6, e := quick.Load(mustGetMcConfigPath(), newConfigV6())
	fatalIf(probe.NewError(e), "Unable to load config.")

	if brokenMcCfgV6.Version() != "6" {
		return
	}

	newCfgV6 := newConfigV6()
	isMutated := false

	// Copy aliases.
	for k, v := range brokenMcCfgV6.Data().(*configV6).Aliases {
		newCfgV6.Aliases[k] = v
	}

	url := &clientURL{}
	// Copy hosts.
	for host, hostCfgV6 := range brokenMcCfgV6.Data().(*configV6).Hosts {
		// Already fixed - Copy and move on.
		if strings.HasPrefix(host, "https") || strings.HasPrefix(host, "http") {
			newCfgV6.Hosts[host] = hostCfgV6
			continue
		}

		// If host entry does not contain "http(s)", introduce a new entry and delete the old one.
		if host == "s3.amazonaws.com" || host == "storage.googleapis.com" ||
			host == "localhost:9000" || host == "127.0.0.1:9000" ||
			host == "play.minio.io:9000" || host == "dl.minio.io:9000" {
			console.Infoln("Found broken host entries, replacing " + host + " with https://" + host + ".")
			url.Host = host
			url.Scheme = "https"
			url.SchemeSeparator = "://"
			newCfgV6.Hosts[url.String()] = hostCfgV6
			isMutated = true
			continue
		}
	}

	if isMutated {
		// Save the new config back to the disk.
		mcCfgV6, e := quick.New(newCfgV6)
		fatalIf(probe.NewError(e), "Unable to initialize quick config for config version ‘v6’.")

		e = mcCfgV6.Save(mustGetMcConfigPath())
		fatalIf(probe.NewError(e), "Unable to save config version ‘v6’.")
	}
}
Esempio n. 30
0
func (s *MySuite) TestLoadFile(c *C) {
	type myStruct struct {
		Version  string
		User     string
		Password string
		Folders  []string
	}
	saveMe := myStruct{}
	_, err := quick.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)
	c.Assert(err, Not(IsNil))
	config, err := quick.New(&saveMe)
	c.Assert(err, IsNil)
	err = config.Load("test-non-exist.json")
	c.Assert(err, Not(IsNil))
	err = config.Load("test.json")
	c.Assert(err, Not(IsNil))

	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)
	saveMe1 := myStruct{}
	_, err = quick.Load("test.json", &saveMe1)
	c.Assert(err, IsNil)
	c.Assert(saveMe1, DeepEquals, saveMe)

	saveMe2 := myStruct{}
	err = json.Unmarshal([]byte(config.String()), &saveMe2)
	c.Assert(err, IsNil)
	c.Assert(saveMe2, DeepEquals, saveMe1)
}