config: Add browser parameter (#3807)

browser new parameter receives "on" or "off" parameter which is similar
to MINIO_BROWSER
master
Anis Elleuch 8 years ago committed by Harshavardhana
parent c9619673fb
commit 9b3c014bab
  1. 106
      cmd/config-migrate.go
  2. 12
      cmd/config-migrate_test.go
  3. 28
      cmd/config-old.go
  4. 75
      cmd/config-v14.go
  5. 51
      cmd/config-v14_test.go
  6. 14
      cmd/globals.go
  7. 16
      cmd/main.go
  8. 2
      cmd/test-utils_test.go
  9. 24
      cmd/utils.go

@ -74,6 +74,10 @@ func migrateConfig() error {
if err := migrateV12ToV13(); err != nil { if err := migrateV12ToV13(); err != nil {
return err return err
} }
// Migration version '13' to '14'.
if err := migrateV13ToV14(); err != nil {
return err
}
return nil return nil
} }
@ -937,3 +941,105 @@ func migrateV12ToV13() error {
) )
return nil return nil
} }
// Version '13' to '14' migration. Add support for custom webhook endpoint.
func migrateV13ToV14() error {
cv13, err := loadConfigV13()
if err != nil {
if os.IsNotExist(err) {
return nil
}
return fmt.Errorf("Unable to load config version ‘13’. %v", err)
}
if cv13.Version != "13" {
return nil
}
// Copy over fields from V13 into V14 config struct
srvConfig := &serverConfigV14{
Logger: &logger{},
Notify: &notifier{},
}
srvConfig.Version = "14"
srvConfig.Credential = cv13.Credential
srvConfig.Region = cv13.Region
if srvConfig.Region == "" {
// Region needs to be set for AWS Signature Version 4.
srvConfig.Region = globalMinioDefaultRegion
}
srvConfig.Logger.Console = cv13.Logger.Console
srvConfig.Logger.File = cv13.Logger.File
// check and set notifiers config
if len(cv13.Notify.AMQP) == 0 {
srvConfig.Notify.AMQP = make(map[string]amqpNotify)
srvConfig.Notify.AMQP["1"] = amqpNotify{}
} else {
srvConfig.Notify.AMQP = cv13.Notify.AMQP
}
if len(cv13.Notify.ElasticSearch) == 0 {
srvConfig.Notify.ElasticSearch = make(map[string]elasticSearchNotify)
srvConfig.Notify.ElasticSearch["1"] = elasticSearchNotify{}
} else {
srvConfig.Notify.ElasticSearch = cv13.Notify.ElasticSearch
}
if len(cv13.Notify.Redis) == 0 {
srvConfig.Notify.Redis = make(map[string]redisNotify)
srvConfig.Notify.Redis["1"] = redisNotify{}
} else {
srvConfig.Notify.Redis = cv13.Notify.Redis
}
if len(cv13.Notify.PostgreSQL) == 0 {
srvConfig.Notify.PostgreSQL = make(map[string]postgreSQLNotify)
srvConfig.Notify.PostgreSQL["1"] = postgreSQLNotify{}
} else {
srvConfig.Notify.PostgreSQL = cv13.Notify.PostgreSQL
}
if len(cv13.Notify.Kafka) == 0 {
srvConfig.Notify.Kafka = make(map[string]kafkaNotify)
srvConfig.Notify.Kafka["1"] = kafkaNotify{}
} else {
srvConfig.Notify.Kafka = cv13.Notify.Kafka
}
if len(cv13.Notify.NATS) == 0 {
srvConfig.Notify.NATS = make(map[string]natsNotify)
srvConfig.Notify.NATS["1"] = natsNotify{}
} else {
srvConfig.Notify.NATS = cv13.Notify.NATS
}
if len(cv13.Notify.Webhook) == 0 {
srvConfig.Notify.Webhook = make(map[string]webhookNotify)
srvConfig.Notify.Webhook["1"] = webhookNotify{}
} else {
srvConfig.Notify.Webhook = cv13.Notify.Webhook
}
// 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)
}
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 ‘"+
cv13.Version+"’ to ‘"+srvConfig.Version+
"’ failed. %v", err,
)
}
console.Println(
"Migration from version ‘" +
cv13.Version + "’ to ‘" + srvConfig.Version +
"’ completed successfully.",
)
return nil
}

@ -50,7 +50,7 @@ func TestServerConfigMigrateV1(t *testing.T) {
} }
// Initialize server config and check again if everything is fine // Initialize server config and check again if everything is fine
if err := loadConfig(credential{}); err != nil { if err := loadConfig(envParams{}); err != nil {
t.Fatalf("Unable to initialize from updated config file %s", err) t.Fatalf("Unable to initialize from updated config file %s", err)
} }
} }
@ -106,10 +106,13 @@ func TestServerConfigMigrateInexistentConfig(t *testing.T) {
if err := migrateV12ToV13(); err != nil { if err := migrateV12ToV13(); err != nil {
t.Fatal("migrate v12 to v13 should succeed when no config file is found") t.Fatal("migrate v12 to v13 should succeed when no config file is found")
} }
if err := migrateV13ToV14(); err != nil {
t.Fatal("migrate v13 to v14 should succeed when no config file is found")
}
} }
// Test if a config migration from v2 to v12 is successfully done // Test if a config migration from v2 to v12 is successfully done
func TestServerConfigMigrateV2toV12(t *testing.T) { func TestServerConfigMigrateV2toV14(t *testing.T) {
rootPath, err := newTestConfig(globalMinioDefaultRegion) rootPath, err := newTestConfig(globalMinioDefaultRegion)
if err != nil { if err != nil {
t.Fatalf("Init Test config failed") t.Fatalf("Init Test config failed")
@ -143,7 +146,7 @@ func TestServerConfigMigrateV2toV12(t *testing.T) {
} }
// Initialize server config and check again if everything is fine // Initialize server config and check again if everything is fine
if err := loadConfig(credential{}); err != nil { if err := loadConfig(envParams{}); err != nil {
t.Fatalf("Unable to initialize from updated config file %s", err) t.Fatalf("Unable to initialize from updated config file %s", err)
} }
@ -213,4 +216,7 @@ func TestServerConfigMigrateFaultyConfig(t *testing.T) {
if err := migrateV12ToV13(); err == nil { if err := migrateV12ToV13(); err == nil {
t.Fatal("migrateConfigV12ToV13() should fail with a corrupted json") t.Fatal("migrateConfigV12ToV13() should fail with a corrupted json")
} }
if err := migrateV13ToV14(); err == nil {
t.Fatal("migrateConfigV13ToV14() should fail with a corrupted json")
}
} }

@ -522,3 +522,31 @@ func loadConfigV12() (*serverConfigV12, error) {
} }
return config.(*serverConfigV12), 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 {
Version string `json:"version"`
// S3 API configuration.
Credential credential `json:"credential"`
Region string `json:"region"`
// Additional error logging configuration.
Logger *logger `json:"logger"`
// Notification queue configuration.
Notify *notifier `json:"notify"`
}
func loadConfigV13() (*serverConfigV13, error) {
configFile, err := getConfigFile()
if err != nil {
return nil, err
}
config, err := loadOldConfig(configFile, &serverConfigV13{Version: "13"})
if config == nil {
return nil, err
}
return config.(*serverConfigV13), err
}

@ -18,6 +18,7 @@ package cmd
import ( import (
"os" "os"
"strings"
"sync" "sync"
"github.com/minio/minio/pkg/quick" "github.com/minio/minio/pkg/quick"
@ -26,14 +27,15 @@ import (
// Read Write mutex for safe access to ServerConfig. // Read Write mutex for safe access to ServerConfig.
var serverConfigMu sync.RWMutex var serverConfigMu sync.RWMutex
// serverConfigV13 server configuration version '13' which is like // serverConfigV14 server configuration version '14' which is like
// version '12' except it adds support for webhook notification. // version '13' except it adds support of browser param.
type serverConfigV13 struct { type serverConfigV14 struct {
Version string `json:"version"` Version string `json:"version"`
// S3 API configuration. // S3 API configuration.
Credential credential `json:"credential"` Credential credential `json:"credential"`
Region string `json:"region"` Region string `json:"region"`
Browser string `json:"browser"`
// Additional error logging configuration. // Additional error logging configuration.
Logger *logger `json:"logger"` Logger *logger `json:"logger"`
@ -42,12 +44,11 @@ type serverConfigV13 struct {
Notify *notifier `json:"notify"` Notify *notifier `json:"notify"`
} }
// newConfig - initialize a new server config, saves creds from env // newConfig - initialize a new server config, saves env parameters if
// if globalIsEnvCreds is set otherwise generates a new set of keys // found, otherwise use default parameters
// and those are saved. func newConfig(envParams envParams) error {
func newConfig(envCreds credential) error {
// Initialize server config. // Initialize server config.
srvCfg := &serverConfigV13{ srvCfg := &serverConfigV14{
Logger: &logger{}, Logger: &logger{},
Notify: &notifier{}, Notify: &notifier{},
} }
@ -56,11 +57,17 @@ func newConfig(envCreds credential) error {
// If env is set for a fresh start, save them to config file. // If env is set for a fresh start, save them to config file.
if globalIsEnvCreds { if globalIsEnvCreds {
srvCfg.SetCredential(envCreds) srvCfg.SetCredential(envParams.creds)
} else { } else {
srvCfg.SetCredential(newCredential()) srvCfg.SetCredential(newCredential())
} }
if globalIsEnvBrowser {
srvCfg.SetBrowser(envParams.browser)
} else {
srvCfg.SetBrowser("on")
}
// Enable console logger by default on a fresh run. // Enable console logger by default on a fresh run.
srvCfg.Logger.Console = consoleLogger{ srvCfg.Logger.Console = consoleLogger{
Enable: true, Enable: true,
@ -99,10 +106,9 @@ func newConfig(envCreds credential) error {
return serverConfig.Save() return serverConfig.Save()
} }
// loadConfig - loads a new config from disk, overrides creds from env // loadConfig - loads a new config from disk, overrides params from env
// if globalIsEnvCreds is set otherwise serves the creds from loaded // if found and valid
// from the disk. func loadConfig(envParams envParams) error {
func loadConfig(envCreds credential) error {
configFile, err := getConfigFile() configFile, err := getConfigFile()
if err != nil { if err != nil {
return err return err
@ -111,7 +117,7 @@ func loadConfig(envCreds credential) error {
if _, err = os.Stat(configFile); err != nil { if _, err = os.Stat(configFile); err != nil {
return err return err
} }
srvCfg := &serverConfigV13{} srvCfg := &serverConfigV14{}
srvCfg.Version = globalMinioConfigVersion srvCfg.Version = globalMinioConfigVersion
qc, err := quick.New(srvCfg) qc, err := quick.New(srvCfg)
if err != nil { if err != nil {
@ -124,11 +130,19 @@ func loadConfig(envCreds credential) error {
// If env is set override the credentials from config file. // If env is set override the credentials from config file.
if globalIsEnvCreds { if globalIsEnvCreds {
srvCfg.SetCredential(envCreds) srvCfg.SetCredential(envParams.creds)
} else { } else {
srvCfg.SetCredential(srvCfg.Credential) srvCfg.SetCredential(srvCfg.Credential)
} }
if globalIsEnvBrowser {
srvCfg.SetBrowser(envParams.browser)
}
if strings.ToLower(srvCfg.GetBrowser()) == "off" {
globalIsBrowserEnabled = false
}
// hold the mutex lock before a new config is assigned. // hold the mutex lock before a new config is assigned.
serverConfigMu.Lock() serverConfigMu.Lock()
// Save the loaded config globally. // Save the loaded config globally.
@ -141,10 +155,10 @@ func loadConfig(envCreds credential) error {
} }
// serverConfig server config. // serverConfig server config.
var serverConfig *serverConfigV13 var serverConfig *serverConfigV14
// GetVersion get current config version. // GetVersion get current config version.
func (s serverConfigV13) GetVersion() string { func (s serverConfigV14) GetVersion() string {
serverConfigMu.RLock() serverConfigMu.RLock()
defer serverConfigMu.RUnlock() defer serverConfigMu.RUnlock()
@ -152,7 +166,7 @@ func (s serverConfigV13) GetVersion() string {
} }
// SetRegion set new region. // SetRegion set new region.
func (s *serverConfigV13) SetRegion(region string) { func (s *serverConfigV14) SetRegion(region string) {
serverConfigMu.Lock() serverConfigMu.Lock()
defer serverConfigMu.Unlock() defer serverConfigMu.Unlock()
@ -160,7 +174,7 @@ func (s *serverConfigV13) SetRegion(region string) {
} }
// GetRegion get current region. // GetRegion get current region.
func (s serverConfigV13) GetRegion() string { func (s serverConfigV14) GetRegion() string {
serverConfigMu.RLock() serverConfigMu.RLock()
defer serverConfigMu.RUnlock() defer serverConfigMu.RUnlock()
@ -168,7 +182,7 @@ func (s serverConfigV13) GetRegion() string {
} }
// SetCredentials set new credentials. // SetCredentials set new credentials.
func (s *serverConfigV13) SetCredential(creds credential) { func (s *serverConfigV14) SetCredential(creds credential) {
serverConfigMu.Lock() serverConfigMu.Lock()
defer serverConfigMu.Unlock() defer serverConfigMu.Unlock()
@ -177,15 +191,32 @@ func (s *serverConfigV13) SetCredential(creds credential) {
} }
// GetCredentials get current credentials. // GetCredentials get current credentials.
func (s serverConfigV13) GetCredential() credential { func (s serverConfigV14) GetCredential() credential {
serverConfigMu.RLock() serverConfigMu.RLock()
defer serverConfigMu.RUnlock() defer serverConfigMu.RUnlock()
return s.Credential return s.Credential
} }
// SetBrowser set if browser is enabled.
func (s *serverConfigV14) SetBrowser(v string) {
serverConfigMu.Lock()
defer serverConfigMu.Unlock()
// Set browser param
s.Browser = v
}
// GetCredentials get current credentials.
func (s serverConfigV14) GetBrowser() string {
serverConfigMu.RLock()
defer serverConfigMu.RUnlock()
return s.Browser
}
// Save config. // Save config.
func (s serverConfigV13) Save() error { func (s serverConfigV14) Save() error {
serverConfigMu.RLock() serverConfigMu.RLock()
defer serverConfigMu.RUnlock() defer serverConfigMu.RUnlock()

@ -17,6 +17,7 @@
package cmd package cmd
import ( import (
"os"
"reflect" "reflect"
"testing" "testing"
) )
@ -114,7 +115,55 @@ func TestServerConfig(t *testing.T) {
setGlobalConfigPath(rootPath) setGlobalConfigPath(rootPath)
// Initialize server config. // Initialize server config.
if err := loadConfig(credential{}); err != nil { if err := loadConfig(envParams{}); err != nil {
t.Fatalf("Unable to initialize from updated config file %s", err) t.Fatalf("Unable to initialize from updated config file %s", err)
} }
} }
func TestServerConfigWithEnvs(t *testing.T) {
os.Setenv("MINIO_BROWSER", "off")
defer os.Unsetenv("MINIO_BROWSER")
os.Setenv("MINIO_ACCESS_KEY", "minio")
defer os.Unsetenv("MINIO_ACCESS_KEY")
os.Setenv("MINIO_SECRET_KEY", "minio123")
defer os.Unsetenv("MINIO_SECRET_KEY")
defer func() {
globalIsEnvBrowser = false
globalIsEnvCreds = false
}()
// Get test root.
rootPath, err := getTestRoot()
if err != nil {
t.Error(err)
}
// Do this only once here.
setGlobalConfigPath(rootPath)
// Init config
initConfig()
// remove the root directory after the test ends.
defer removeAll(rootPath)
// Check if serverConfig has
if serverConfig.GetBrowser() != "off" {
t.Errorf("Expecting browser `off` found %s", serverConfig.GetBrowser())
}
// Check if serverConfig has
cred := serverConfig.GetCredential()
if cred.AccessKey != "minio" {
t.Errorf("Expecting access key to be `minio` found %s", cred.AccessKey)
}
if cred.SecretKey != "minio123" {
t.Errorf("Expecting access key to be `minio123` found %s", cred.SecretKey)
}
}

@ -19,9 +19,7 @@ package cmd
import ( import (
"crypto/x509" "crypto/x509"
"net/url" "net/url"
"os"
"runtime" "runtime"
"strings"
"time" "time"
humanize "github.com/dustin/go-humanize" humanize "github.com/dustin/go-humanize"
@ -74,9 +72,12 @@ var (
// Indicates if the running minio server is an erasure-code backend. // Indicates if the running minio server is an erasure-code backend.
globalIsXL = false globalIsXL = false
// This flag is set to 'true' by default, it is set to `false` // This flag is set to 'true' by default
// when MINIO_BROWSER env is set to 'off'. globalIsBrowserEnabled = true
globalIsBrowserEnabled = !strings.EqualFold(os.Getenv("MINIO_BROWSER"), "off") // This flag is set to 'true' when MINIO_BROWSER env is set.
globalIsEnvBrowser = false
// Set to true if credentials were passed from env, default is false.
globalIsEnvCreds = false
// Maximum cache size. Defaults to disabled. // Maximum cache size. Defaults to disabled.
// Caching is enabled only for RAM size > 8GiB. // Caching is enabled only for RAM size > 8GiB.
@ -113,9 +114,6 @@ var (
// Minio server user agent string. // Minio server user agent string.
globalServerUserAgent = "Minio/" + ReleaseTag + " (" + runtime.GOOS + "; " + runtime.GOARCH + ")" globalServerUserAgent = "Minio/" + ReleaseTag + " (" + runtime.GOOS + "; " + runtime.GOARCH + ")"
// Set to true if credentials were passed from env, default is false.
globalIsEnvCreds = false
// url.URL endpoints of disks that belong to the object storage. // url.URL endpoints of disks that belong to the object storage.
globalEndpoints = []*url.URL{} globalEndpoints = []*url.URL{}

@ -159,14 +159,24 @@ func checkUpdate() {
} }
} }
// envParams holds all env parameters
type envParams struct {
creds credential
browser string
}
// Initializes a new config if it doesn't exist, else migrates any old config // Initializes a new config if it doesn't exist, else migrates any old config
// to newer config and finally loads the config to memory. // to newer config and finally loads the config to memory.
func initConfig() { func initConfig() {
envCreds := mustGetCredentialFromEnv()
envs := envParams{
creds: mustGetCredentialFromEnv(),
browser: mustGetBrowserFromEnv(),
}
// Config file does not exist, we create it fresh and return upon success. // Config file does not exist, we create it fresh and return upon success.
if !isConfigFileExists() { if !isConfigFileExists() {
if err := newConfig(envCreds); err != nil { if err := newConfig(envs); err != nil {
console.Fatalf("Unable to initialize minio config for the first time. Err: %s.\n", err) console.Fatalf("Unable to initialize minio config for the first time. Err: %s.\n", err)
} }
console.Println("Created minio configuration file successfully at " + mustGetConfigPath()) console.Println("Created minio configuration file successfully at " + mustGetConfigPath())
@ -177,7 +187,7 @@ func initConfig() {
migrate() migrate()
// Once we have migrated all the old config, now load them. // Once we have migrated all the old config, now load them.
if err := loadConfig(envCreds); err != nil { if err := loadConfig(envs); err != nil {
console.Fatalf("Unable to initialize minio config. Err: %s.\n", err) console.Fatalf("Unable to initialize minio config. Err: %s.\n", err)
} }
} }

@ -533,7 +533,7 @@ func newTestConfig(bucketLocation string) (rootPath string, err error) {
setGlobalConfigPath(rootPath) setGlobalConfigPath(rootPath)
// Initialize server config. // Initialize server config.
if err = newConfig(credential{}); err != nil { if err = newConfig(envParams{}); err != nil {
return "", err return "", err
} }

@ -23,11 +23,13 @@ import (
"io" "io"
"net/http" "net/http"
"net/url" "net/url"
"os"
"strings" "strings"
"encoding/json" "encoding/json"
humanize "github.com/dustin/go-humanize" humanize "github.com/dustin/go-humanize"
"github.com/minio/mc/pkg/console"
"github.com/pkg/profile" "github.com/pkg/profile"
) )
@ -238,3 +240,25 @@ func dumpRequest(r *http.Request) string {
} }
return string(jsonBytes) return string(jsonBytes)
} }
// Variant of getBrowserFromEnv but upon error fails right here.
func mustGetBrowserFromEnv() string {
browser, err := getBrowserFromEnv()
if err != nil {
console.Fatalf("Unable to load MINIO_BROWSER value from environment. Err: %s.\n", err)
}
return browser
}
//
func getBrowserFromEnv() (string, error) {
b := os.Getenv("MINIO_BROWSER")
if strings.TrimSpace(b) == "" {
return "", nil
}
if !strings.EqualFold(b, "off") && !strings.EqualFold(b, "on") {
return "", errInvalidArgument
}
globalIsEnvBrowser = true
return strings.ToLower(b), nil
}

Loading…
Cancel
Save