mirror of https://github.com/minio/minio.git
Persist MINIO_WORM as part of config.json (#6022)
This commit is contained in:
parent
113570b514
commit
6138cae8e7
|
@ -42,7 +42,7 @@ export class ChangePasswordModal extends React.Component {
|
||||||
const { serverInfo } = this.props
|
const { serverInfo } = this.props
|
||||||
|
|
||||||
// Check environment variables first.
|
// Check environment variables first.
|
||||||
if (serverInfo.info.isEnvCreds) {
|
if (serverInfo.info.isEnvCreds || serverInfo.info.isWorm) {
|
||||||
this.setState({
|
this.setState({
|
||||||
accessKey: "xxxxxxxxx",
|
accessKey: "xxxxxxxxx",
|
||||||
secretKey: "xxxxxxxxx",
|
secretKey: "xxxxxxxxx",
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -68,7 +68,7 @@ var (
|
||||||
func (a adminAPIHandlers) VersionHandler(w http.ResponseWriter, r *http.Request) {
|
func (a adminAPIHandlers) VersionHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
adminAPIErr := checkAdminRequestAuthType(r, globalServerConfig.GetRegion())
|
adminAPIErr := checkAdminRequestAuthType(r, globalServerConfig.GetRegion())
|
||||||
if adminAPIErr != ErrNone {
|
if adminAPIErr != ErrNone {
|
||||||
writeErrorResponse(w, adminAPIErr, r.URL)
|
writeErrorResponseJSON(w, adminAPIErr, r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,6 +669,12 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deny if WORM is enabled
|
||||||
|
if globalWORMEnabled {
|
||||||
|
writeErrorResponseJSON(w, ErrMethodNotAllowed, r.URL)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Validate request signature.
|
// Validate request signature.
|
||||||
adminAPIErr := checkAdminRequestAuthType(r, globalServerConfig.GetRegion())
|
adminAPIErr := checkAdminRequestAuthType(r, globalServerConfig.GetRegion())
|
||||||
if adminAPIErr != ErrNone {
|
if adminAPIErr != ErrNone {
|
||||||
|
@ -681,12 +687,12 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques
|
||||||
n, err := io.ReadFull(r.Body, configBuf)
|
n, err := io.ReadFull(r.Body, configBuf)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// More than maxConfigSize bytes were available
|
// More than maxConfigSize bytes were available
|
||||||
writeErrorResponse(w, ErrAdminConfigTooLarge, r.URL)
|
writeErrorResponseJSON(w, ErrAdminConfigTooLarge, r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != io.ErrUnexpectedEOF {
|
if err != io.ErrUnexpectedEOF {
|
||||||
logger.LogIf(ctx, err)
|
logger.LogIf(ctx, err)
|
||||||
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
|
writeErrorResponseJSON(w, toAPIErrorCode(err), r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,7 +702,7 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques
|
||||||
// client has not sent JSON objects with duplicate keys.
|
// client has not sent JSON objects with duplicate keys.
|
||||||
if err = quick.CheckDuplicateKeys(string(configBytes)); err != nil {
|
if err = quick.CheckDuplicateKeys(string(configBytes)); err != nil {
|
||||||
logger.LogIf(ctx, err)
|
logger.LogIf(ctx, err)
|
||||||
writeErrorResponse(w, ErrAdminConfigBadJSON, r.URL)
|
writeErrorResponseJSON(w, ErrAdminConfigBadJSON, r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,7 +710,7 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques
|
||||||
err = json.Unmarshal(configBytes, &config)
|
err = json.Unmarshal(configBytes, &config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.LogIf(ctx, err)
|
logger.LogIf(ctx, err)
|
||||||
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
|
writeErrorResponseJSON(w, toAPIErrorCode(err), r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,14 +775,14 @@ func (a adminAPIHandlers) UpdateCredentialsHandler(w http.ResponseWriter,
|
||||||
// Authenticate request
|
// Authenticate request
|
||||||
adminAPIErr := checkAdminRequestAuthType(r, globalServerConfig.GetRegion())
|
adminAPIErr := checkAdminRequestAuthType(r, globalServerConfig.GetRegion())
|
||||||
if adminAPIErr != ErrNone {
|
if adminAPIErr != ErrNone {
|
||||||
writeErrorResponse(w, adminAPIErr, r.URL)
|
writeErrorResponseJSON(w, adminAPIErr, r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid setting new credentials when they are already passed
|
// Avoid setting new credentials when they are already passed
|
||||||
// by the environment.
|
// by the environment. Deny if WORM is enabled.
|
||||||
if globalIsEnvCreds {
|
if globalIsEnvCreds || globalWORMEnabled {
|
||||||
writeErrorResponse(w, ErrMethodNotAllowed, r.URL)
|
writeErrorResponseJSON(w, ErrMethodNotAllowed, r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,7 +797,7 @@ func (a adminAPIHandlers) UpdateCredentialsHandler(w http.ResponseWriter,
|
||||||
|
|
||||||
creds, err := auth.CreateCredentials(req.AccessKey, req.SecretKey)
|
creds, err := auth.CreateCredentials(req.AccessKey, req.SecretKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
|
writeErrorResponseJSON(w, toAPIErrorCode(err), r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -811,7 +817,7 @@ func (a adminAPIHandlers) UpdateCredentialsHandler(w http.ResponseWriter,
|
||||||
// Update local credentials in memory.
|
// Update local credentials in memory.
|
||||||
globalServerConfig.SetCredential(creds)
|
globalServerConfig.SetCredential(creds)
|
||||||
if err = globalServerConfig.Save(); err != nil {
|
if err = globalServerConfig.Save(); err != nil {
|
||||||
writeErrorResponse(w, ErrInternalError, r.URL)
|
writeErrorResponseJSON(w, ErrInternalError, r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Minio Cloud Storage, (C) 2017 Minio, Inc.
|
* Minio Cloud Storage, (C) 2017, 2018 Minio, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -21,11 +21,11 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BrowserFlag - wrapper bool type.
|
// BoolFlag - wrapper bool type.
|
||||||
type BrowserFlag bool
|
type BoolFlag bool
|
||||||
|
|
||||||
// String - returns string of BrowserFlag.
|
// String - returns string of BoolFlag.
|
||||||
func (bf BrowserFlag) String() string {
|
func (bf BoolFlag) String() string {
|
||||||
if bf {
|
if bf {
|
||||||
return "on"
|
return "on"
|
||||||
}
|
}
|
||||||
|
@ -33,20 +33,20 @@ func (bf BrowserFlag) String() string {
|
||||||
return "off"
|
return "off"
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON - converts BrowserFlag into JSON data.
|
// MarshalJSON - converts BoolFlag into JSON data.
|
||||||
func (bf BrowserFlag) MarshalJSON() ([]byte, error) {
|
func (bf BoolFlag) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(bf.String())
|
return json.Marshal(bf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON - parses given data into BrowserFlag.
|
// UnmarshalJSON - parses given data into BoolFlag.
|
||||||
func (bf *BrowserFlag) UnmarshalJSON(data []byte) (err error) {
|
func (bf *BoolFlag) UnmarshalJSON(data []byte) (err error) {
|
||||||
var s string
|
var s string
|
||||||
if err = json.Unmarshal(data, &s); err == nil {
|
if err = json.Unmarshal(data, &s); err == nil {
|
||||||
b := BrowserFlag(true)
|
b := BoolFlag(true)
|
||||||
if s == "" {
|
if s == "" {
|
||||||
// Empty string is treated as valid.
|
// Empty string is treated as valid.
|
||||||
*bf = b
|
*bf = b
|
||||||
} else if b, err = ParseBrowserFlag(s); err == nil {
|
} else if b, err = ParseBoolFlag(s); err == nil {
|
||||||
*bf = b
|
*bf = b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,14 +54,14 @@ func (bf *BrowserFlag) UnmarshalJSON(data []byte) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseBrowserFlag - parses string into BrowserFlag.
|
// ParseBoolFlag - parses string into BoolFlag.
|
||||||
func ParseBrowserFlag(s string) (bf BrowserFlag, err error) {
|
func ParseBoolFlag(s string) (bf BoolFlag, err error) {
|
||||||
if s == "on" {
|
if s == "on" {
|
||||||
bf = true
|
bf = true
|
||||||
} else if s == "off" {
|
} else if s == "off" {
|
||||||
bf = false
|
bf = false
|
||||||
} else {
|
} else {
|
||||||
err = fmt.Errorf("invalid value ‘%s’ for BrowserFlag", s)
|
err = fmt.Errorf("invalid value ‘%s’ for BoolFlag", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return bf, err
|
return bf, err
|
|
@ -21,17 +21,17 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test BrowserFlag.String()
|
// Test BoolFlag.String()
|
||||||
func TestBrowserFlagString(t *testing.T) {
|
func TestBoolFlagString(t *testing.T) {
|
||||||
var bf BrowserFlag
|
var bf BoolFlag
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
flag BrowserFlag
|
flag BoolFlag
|
||||||
expectedResult string
|
expectedResult string
|
||||||
}{
|
}{
|
||||||
{bf, "off"},
|
{bf, "off"},
|
||||||
{BrowserFlag(true), "on"},
|
{BoolFlag(true), "on"},
|
||||||
{BrowserFlag(false), "off"},
|
{BoolFlag(false), "off"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
|
@ -42,17 +42,17 @@ func TestBrowserFlagString(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test BrowserFlag.MarshalJSON()
|
// Test BoolFlag.MarshalJSON()
|
||||||
func TestBrowserFlagMarshalJSON(t *testing.T) {
|
func TestBoolFlagMarshalJSON(t *testing.T) {
|
||||||
var bf BrowserFlag
|
var bf BoolFlag
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
flag BrowserFlag
|
flag BoolFlag
|
||||||
expectedResult string
|
expectedResult string
|
||||||
}{
|
}{
|
||||||
{bf, `"off"`},
|
{bf, `"off"`},
|
||||||
{BrowserFlag(true), `"on"`},
|
{BoolFlag(true), `"on"`},
|
||||||
{BrowserFlag(false), `"off"`},
|
{BoolFlag(false), `"off"`},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
|
@ -63,27 +63,27 @@ func TestBrowserFlagMarshalJSON(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test BrowserFlag.UnmarshalJSON()
|
// Test BoolFlag.UnmarshalJSON()
|
||||||
func TestBrowserFlagUnmarshalJSON(t *testing.T) {
|
func TestBoolFlagUnmarshalJSON(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
data []byte
|
data []byte
|
||||||
expectedResult BrowserFlag
|
expectedResult BoolFlag
|
||||||
expectedErr error
|
expectedErr error
|
||||||
}{
|
}{
|
||||||
{[]byte(`{}`), BrowserFlag(false), errors.New("json: cannot unmarshal object into Go value of type string")},
|
{[]byte(`{}`), BoolFlag(false), errors.New("json: cannot unmarshal object into Go value of type string")},
|
||||||
{[]byte(`["on"]`), BrowserFlag(false), errors.New("json: cannot unmarshal array into Go value of type string")},
|
{[]byte(`["on"]`), BoolFlag(false), errors.New("json: cannot unmarshal array into Go value of type string")},
|
||||||
{[]byte(`"junk"`), BrowserFlag(false), errors.New("invalid value ‘junk’ for BrowserFlag")},
|
{[]byte(`"junk"`), BoolFlag(false), errors.New("invalid value ‘junk’ for BoolFlag")},
|
||||||
{[]byte(`"true"`), BrowserFlag(false), errors.New("invalid value ‘true’ for BrowserFlag")},
|
{[]byte(`"true"`), BoolFlag(false), errors.New("invalid value ‘true’ for BoolFlag")},
|
||||||
{[]byte(`"false"`), BrowserFlag(false), errors.New("invalid value ‘false’ for BrowserFlag")},
|
{[]byte(`"false"`), BoolFlag(false), errors.New("invalid value ‘false’ for BoolFlag")},
|
||||||
{[]byte(`"ON"`), BrowserFlag(false), errors.New("invalid value ‘ON’ for BrowserFlag")},
|
{[]byte(`"ON"`), BoolFlag(false), errors.New("invalid value ‘ON’ for BoolFlag")},
|
||||||
{[]byte(`"OFF"`), BrowserFlag(false), errors.New("invalid value ‘OFF’ for BrowserFlag")},
|
{[]byte(`"OFF"`), BoolFlag(false), errors.New("invalid value ‘OFF’ for BoolFlag")},
|
||||||
{[]byte(`""`), BrowserFlag(true), nil},
|
{[]byte(`""`), BoolFlag(true), nil},
|
||||||
{[]byte(`"on"`), BrowserFlag(true), nil},
|
{[]byte(`"on"`), BoolFlag(true), nil},
|
||||||
{[]byte(`"off"`), BrowserFlag(false), nil},
|
{[]byte(`"off"`), BoolFlag(false), nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
var flag BrowserFlag
|
var flag BoolFlag
|
||||||
err := (&flag).UnmarshalJSON(testCase.data)
|
err := (&flag).UnmarshalJSON(testCase.data)
|
||||||
if testCase.expectedErr == nil {
|
if testCase.expectedErr == nil {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -101,25 +101,25 @@ func TestBrowserFlagUnmarshalJSON(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test ParseBrowserFlag()
|
// Test ParseBoolFlag()
|
||||||
func TestParseBrowserFlag(t *testing.T) {
|
func TestParseBoolFlag(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
flagStr string
|
flagStr string
|
||||||
expectedResult BrowserFlag
|
expectedResult BoolFlag
|
||||||
expectedErr error
|
expectedErr error
|
||||||
}{
|
}{
|
||||||
{"", BrowserFlag(false), errors.New("invalid value ‘’ for BrowserFlag")},
|
{"", BoolFlag(false), errors.New("invalid value ‘’ for BoolFlag")},
|
||||||
{"junk", BrowserFlag(false), errors.New("invalid value ‘junk’ for BrowserFlag")},
|
{"junk", BoolFlag(false), errors.New("invalid value ‘junk’ for BoolFlag")},
|
||||||
{"true", BrowserFlag(false), errors.New("invalid value ‘true’ for BrowserFlag")},
|
{"true", BoolFlag(false), errors.New("invalid value ‘true’ for BoolFlag")},
|
||||||
{"false", BrowserFlag(false), errors.New("invalid value ‘false’ for BrowserFlag")},
|
{"false", BoolFlag(false), errors.New("invalid value ‘false’ for BoolFlag")},
|
||||||
{"ON", BrowserFlag(false), errors.New("invalid value ‘ON’ for BrowserFlag")},
|
{"ON", BoolFlag(false), errors.New("invalid value ‘ON’ for BoolFlag")},
|
||||||
{"OFF", BrowserFlag(false), errors.New("invalid value ‘OFF’ for BrowserFlag")},
|
{"OFF", BoolFlag(false), errors.New("invalid value ‘OFF’ for BoolFlag")},
|
||||||
{"on", BrowserFlag(true), nil},
|
{"on", BoolFlag(true), nil},
|
||||||
{"off", BrowserFlag(false), nil},
|
{"off", BoolFlag(false), nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
bf, err := ParseBrowserFlag(testCase.flagStr)
|
bf, err := ParseBoolFlag(testCase.flagStr)
|
||||||
if testCase.expectedErr == nil {
|
if testCase.expectedErr == nil {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error: expected = <nil>, got = %v", err)
|
t.Fatalf("error: expected = <nil>, got = %v", err)
|
|
@ -105,7 +105,7 @@ func handleCommonEnvVars() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if browser := os.Getenv("MINIO_BROWSER"); browser != "" {
|
if browser := os.Getenv("MINIO_BROWSER"); browser != "" {
|
||||||
browserFlag, err := ParseBrowserFlag(browser)
|
browserFlag, err := ParseBoolFlag(browser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatal(uiErrInvalidBrowserValue(nil).Msg("Unknown value `%s`", browser), "Unable to validate MINIO_BROWSER environment variable")
|
logger.Fatal(uiErrInvalidBrowserValue(nil).Msg("Unknown value `%s`", browser), "Unable to validate MINIO_BROWSER environment variable")
|
||||||
}
|
}
|
||||||
|
@ -123,10 +123,7 @@ func handleCommonEnvVars() {
|
||||||
logger.FatalIf(err, "error opening file %s", traceFile)
|
logger.FatalIf(err, "error opening file %s", traceFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
globalDomainName = os.Getenv("MINIO_DOMAIN")
|
globalDomainName, globalIsEnvDomainName = os.LookupEnv("MINIO_DOMAIN")
|
||||||
if globalDomainName != "" {
|
|
||||||
globalIsEnvDomainName = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if drives := os.Getenv("MINIO_CACHE_DRIVES"); drives != "" {
|
if drives := os.Getenv("MINIO_CACHE_DRIVES"); drives != "" {
|
||||||
driveList, err := parseCacheDrives(strings.Split(drives, cacheEnvDelimiter))
|
driveList, err := parseCacheDrives(strings.Split(drives, cacheEnvDelimiter))
|
||||||
|
@ -189,5 +186,15 @@ func handleCommonEnvVars() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get WORM environment variable.
|
// Get WORM environment variable.
|
||||||
globalWORMEnabled = strings.EqualFold(os.Getenv("MINIO_WORM"), "on")
|
if worm := os.Getenv("MINIO_WORM"); worm != "" {
|
||||||
|
wormFlag, err := ParseBoolFlag(worm)
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatal(uiErrInvalidWormValue(nil).Msg("Unknown value `%s`", worm), "Unable to validate MINIO_WORM environment variable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// worm Envs are set globally, this does not represent
|
||||||
|
// if worm is turned off or on.
|
||||||
|
globalIsEnvWORM = true
|
||||||
|
globalWORMEnabled = bool(wormFlag)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,9 @@ import (
|
||||||
// 6. Make changes in config-current_test.go for any test change
|
// 6. Make changes in config-current_test.go for any test change
|
||||||
|
|
||||||
// Config version
|
// Config version
|
||||||
const serverConfigVersion = "24"
|
const serverConfigVersion = "25"
|
||||||
|
|
||||||
type serverConfig = serverConfigV24
|
type serverConfig = serverConfigV25
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// globalServerConfig server config.
|
// globalServerConfig server config.
|
||||||
|
@ -85,7 +85,13 @@ func (s *serverConfig) GetCredential() auth.Credentials {
|
||||||
// SetBrowser set if browser is enabled.
|
// SetBrowser set if browser is enabled.
|
||||||
func (s *serverConfig) SetBrowser(b bool) {
|
func (s *serverConfig) SetBrowser(b bool) {
|
||||||
// Set the new value.
|
// Set the new value.
|
||||||
s.Browser = BrowserFlag(b)
|
s.Browser = BoolFlag(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWorm set if worm is enabled.
|
||||||
|
func (s *serverConfig) SetWorm(b bool) {
|
||||||
|
// Set the new value.
|
||||||
|
s.Worm = BoolFlag(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serverConfig) SetStorageClass(standardClass, rrsClass storageClass) {
|
func (s *serverConfig) SetStorageClass(standardClass, rrsClass storageClass) {
|
||||||
|
@ -99,11 +105,16 @@ func (s *serverConfig) GetStorageClass() (storageClass, storageClass) {
|
||||||
return s.StorageClass.Standard, s.StorageClass.RRS
|
return s.StorageClass.Standard, s.StorageClass.RRS
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCredentials get current credentials.
|
// GetBrowser get current credentials.
|
||||||
func (s *serverConfig) GetBrowser() bool {
|
func (s *serverConfig) GetBrowser() bool {
|
||||||
return bool(s.Browser)
|
return bool(s.Browser)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetWorm get current credentials.
|
||||||
|
func (s *serverConfig) GetWorm() bool {
|
||||||
|
return bool(s.Worm)
|
||||||
|
}
|
||||||
|
|
||||||
// SetCacheConfig sets the current cache config
|
// SetCacheConfig sets the current cache config
|
||||||
func (s *serverConfig) SetCacheConfig(drives, exclude []string, expiry int) {
|
func (s *serverConfig) SetCacheConfig(drives, exclude []string, expiry int) {
|
||||||
s.Cache.Drives = drives
|
s.Cache.Drives = drives
|
||||||
|
@ -230,6 +241,10 @@ func newConfig() error {
|
||||||
srvCfg.SetBrowser(globalIsBrowserEnabled)
|
srvCfg.SetBrowser(globalIsBrowserEnabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if globalIsEnvWORM {
|
||||||
|
srvCfg.SetWorm(globalWORMEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
if globalIsEnvRegion {
|
if globalIsEnvRegion {
|
||||||
srvCfg.SetRegion(globalServerRegion)
|
srvCfg.SetRegion(globalServerRegion)
|
||||||
}
|
}
|
||||||
|
@ -324,6 +339,9 @@ func loadConfig() error {
|
||||||
if !globalIsEnvBrowser {
|
if !globalIsEnvBrowser {
|
||||||
globalIsBrowserEnabled = globalServerConfig.GetBrowser()
|
globalIsBrowserEnabled = globalServerConfig.GetBrowser()
|
||||||
}
|
}
|
||||||
|
if !globalIsEnvWORM {
|
||||||
|
globalWORMEnabled = globalServerConfig.GetWorm()
|
||||||
|
}
|
||||||
if !globalIsEnvRegion {
|
if !globalIsEnvRegion {
|
||||||
globalServerRegion = globalServerConfig.GetRegion()
|
globalServerRegion = globalServerConfig.GetRegion()
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,6 +177,11 @@ func migrateConfig() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
|
case "24":
|
||||||
|
if err = migrateV24ToV25(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
case serverConfigVersion:
|
case serverConfigVersion:
|
||||||
// No migration needed. this always points to current version.
|
// No migration needed. this always points to current version.
|
||||||
err = nil
|
err = nil
|
||||||
|
@ -2069,3 +2074,121 @@ func migrateV23ToV24() error {
|
||||||
logger.Info(configMigrateMSGTemplate, configFile, cv23.Version, srvConfig.Version)
|
logger.Info(configMigrateMSGTemplate, configFile, cv23.Version, srvConfig.Version)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func migrateV24ToV25() error {
|
||||||
|
configFile := getConfigFile()
|
||||||
|
|
||||||
|
cv24 := &serverConfigV24{}
|
||||||
|
_, err := quick.Load(configFile, cv24)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return nil
|
||||||
|
} else if err != nil {
|
||||||
|
return fmt.Errorf("Unable to load config version ‘24’. %v", err)
|
||||||
|
}
|
||||||
|
if cv24.Version != "24" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy over fields from V24 into V25 config struct
|
||||||
|
srvConfig := &serverConfigV25{
|
||||||
|
Notify: notifier{},
|
||||||
|
}
|
||||||
|
srvConfig.Version = "25"
|
||||||
|
srvConfig.Credential = cv24.Credential
|
||||||
|
srvConfig.Region = cv24.Region
|
||||||
|
if srvConfig.Region == "" {
|
||||||
|
// Region needs to be set for AWS Signature Version 4.
|
||||||
|
srvConfig.Region = globalMinioDefaultRegion
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cv24.Notify.AMQP) == 0 {
|
||||||
|
srvConfig.Notify.AMQP = make(map[string]target.AMQPArgs)
|
||||||
|
srvConfig.Notify.AMQP["1"] = target.AMQPArgs{}
|
||||||
|
} else {
|
||||||
|
srvConfig.Notify.AMQP = cv24.Notify.AMQP
|
||||||
|
}
|
||||||
|
if len(cv24.Notify.Elasticsearch) == 0 {
|
||||||
|
srvConfig.Notify.Elasticsearch = make(map[string]target.ElasticsearchArgs)
|
||||||
|
srvConfig.Notify.Elasticsearch["1"] = target.ElasticsearchArgs{
|
||||||
|
Format: event.NamespaceFormat,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
srvConfig.Notify.Elasticsearch = cv24.Notify.Elasticsearch
|
||||||
|
}
|
||||||
|
if len(cv24.Notify.Redis) == 0 {
|
||||||
|
srvConfig.Notify.Redis = make(map[string]target.RedisArgs)
|
||||||
|
srvConfig.Notify.Redis["1"] = target.RedisArgs{
|
||||||
|
Format: event.NamespaceFormat,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
srvConfig.Notify.Redis = cv24.Notify.Redis
|
||||||
|
}
|
||||||
|
if len(cv24.Notify.PostgreSQL) == 0 {
|
||||||
|
srvConfig.Notify.PostgreSQL = make(map[string]target.PostgreSQLArgs)
|
||||||
|
srvConfig.Notify.PostgreSQL["1"] = target.PostgreSQLArgs{
|
||||||
|
Format: event.NamespaceFormat,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
srvConfig.Notify.PostgreSQL = cv24.Notify.PostgreSQL
|
||||||
|
}
|
||||||
|
if len(cv24.Notify.Kafka) == 0 {
|
||||||
|
srvConfig.Notify.Kafka = make(map[string]target.KafkaArgs)
|
||||||
|
srvConfig.Notify.Kafka["1"] = target.KafkaArgs{}
|
||||||
|
} else {
|
||||||
|
srvConfig.Notify.Kafka = cv24.Notify.Kafka
|
||||||
|
}
|
||||||
|
if len(cv24.Notify.NATS) == 0 {
|
||||||
|
srvConfig.Notify.NATS = make(map[string]target.NATSArgs)
|
||||||
|
srvConfig.Notify.NATS["1"] = target.NATSArgs{}
|
||||||
|
} else {
|
||||||
|
srvConfig.Notify.NATS = cv24.Notify.NATS
|
||||||
|
}
|
||||||
|
if len(cv24.Notify.Webhook) == 0 {
|
||||||
|
srvConfig.Notify.Webhook = make(map[string]target.WebhookArgs)
|
||||||
|
srvConfig.Notify.Webhook["1"] = target.WebhookArgs{}
|
||||||
|
} else {
|
||||||
|
srvConfig.Notify.Webhook = cv24.Notify.Webhook
|
||||||
|
}
|
||||||
|
if len(cv24.Notify.MySQL) == 0 {
|
||||||
|
srvConfig.Notify.MySQL = make(map[string]target.MySQLArgs)
|
||||||
|
srvConfig.Notify.MySQL["1"] = target.MySQLArgs{
|
||||||
|
Format: event.NamespaceFormat,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
srvConfig.Notify.MySQL = cv24.Notify.MySQL
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cv24.Notify.MQTT) == 0 {
|
||||||
|
srvConfig.Notify.MQTT = make(map[string]target.MQTTArgs)
|
||||||
|
srvConfig.Notify.MQTT["1"] = target.MQTTArgs{}
|
||||||
|
} else {
|
||||||
|
srvConfig.Notify.MQTT = cv24.Notify.MQTT
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load browser config from existing config in the file.
|
||||||
|
srvConfig.Browser = cv24.Browser
|
||||||
|
|
||||||
|
// New field should be turned-off by default.
|
||||||
|
srvConfig.Worm = false // cv25.Worm should be used here
|
||||||
|
// for the next migration from v25 to v26 to persist
|
||||||
|
// local config value.
|
||||||
|
|
||||||
|
// Load domain config from existing config in the file.
|
||||||
|
srvConfig.Domain = cv24.Domain
|
||||||
|
|
||||||
|
// Load storage class config from existing storage class config in the file.
|
||||||
|
srvConfig.StorageClass.RRS = cv24.StorageClass.RRS
|
||||||
|
srvConfig.StorageClass.Standard = cv24.StorageClass.Standard
|
||||||
|
|
||||||
|
// Load cache config from existing cache config in the file.
|
||||||
|
srvConfig.Cache.Drives = cv24.Cache.Drives
|
||||||
|
srvConfig.Cache.Exclude = cv24.Cache.Exclude
|
||||||
|
srvConfig.Cache.Expiry = cv24.Cache.Expiry
|
||||||
|
|
||||||
|
if err = quick.Save(configFile, srvConfig); err != nil {
|
||||||
|
return fmt.Errorf("Failed to migrate config from ‘%s’ to ‘%s’. %v", cv24.Version, srvConfig.Version, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info(configMigrateMSGTemplate, configFile, cv24.Version, srvConfig.Version)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -405,7 +405,7 @@ type serverConfigV14 struct {
|
||||||
// S3 API configuration.
|
// S3 API configuration.
|
||||||
Credential auth.Credentials `json:"credential"`
|
Credential auth.Credentials `json:"credential"`
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
Browser BrowserFlag `json:"browser"`
|
Browser BoolFlag `json:"browser"`
|
||||||
|
|
||||||
// Additional error logging configuration.
|
// Additional error logging configuration.
|
||||||
Logger *loggerV7 `json:"logger"`
|
Logger *loggerV7 `json:"logger"`
|
||||||
|
@ -422,7 +422,7 @@ type serverConfigV15 struct {
|
||||||
// S3 API configuration.
|
// S3 API configuration.
|
||||||
Credential auth.Credentials `json:"credential"`
|
Credential auth.Credentials `json:"credential"`
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
Browser BrowserFlag `json:"browser"`
|
Browser BoolFlag `json:"browser"`
|
||||||
|
|
||||||
// Additional error logging configuration.
|
// Additional error logging configuration.
|
||||||
Logger *loggerV7 `json:"logger"`
|
Logger *loggerV7 `json:"logger"`
|
||||||
|
@ -460,7 +460,7 @@ type serverConfigV16 struct {
|
||||||
// S3 API configuration.
|
// S3 API configuration.
|
||||||
Credential auth.Credentials `json:"credential"`
|
Credential auth.Credentials `json:"credential"`
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
Browser BrowserFlag `json:"browser"`
|
Browser BoolFlag `json:"browser"`
|
||||||
|
|
||||||
// Additional error logging configuration.
|
// Additional error logging configuration.
|
||||||
Logger *loggers `json:"logger"`
|
Logger *loggers `json:"logger"`
|
||||||
|
@ -479,7 +479,7 @@ type serverConfigV17 struct {
|
||||||
// S3 API configuration.
|
// S3 API configuration.
|
||||||
Credential auth.Credentials `json:"credential"`
|
Credential auth.Credentials `json:"credential"`
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
Browser BrowserFlag `json:"browser"`
|
Browser BoolFlag `json:"browser"`
|
||||||
|
|
||||||
// Additional error logging configuration.
|
// Additional error logging configuration.
|
||||||
Logger *loggers `json:"logger"`
|
Logger *loggers `json:"logger"`
|
||||||
|
@ -498,7 +498,7 @@ type serverConfigV18 struct {
|
||||||
// S3 API configuration.
|
// S3 API configuration.
|
||||||
Credential auth.Credentials `json:"credential"`
|
Credential auth.Credentials `json:"credential"`
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
Browser BrowserFlag `json:"browser"`
|
Browser BoolFlag `json:"browser"`
|
||||||
|
|
||||||
// Additional error logging configuration.
|
// Additional error logging configuration.
|
||||||
Logger *loggers `json:"logger"`
|
Logger *loggers `json:"logger"`
|
||||||
|
@ -516,7 +516,7 @@ type serverConfigV19 struct {
|
||||||
// S3 API configuration.
|
// S3 API configuration.
|
||||||
Credential auth.Credentials `json:"credential"`
|
Credential auth.Credentials `json:"credential"`
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
Browser BrowserFlag `json:"browser"`
|
Browser BoolFlag `json:"browser"`
|
||||||
|
|
||||||
// Additional error logging configuration.
|
// Additional error logging configuration.
|
||||||
Logger *loggers `json:"logger"`
|
Logger *loggers `json:"logger"`
|
||||||
|
@ -534,7 +534,7 @@ type serverConfigV20 struct {
|
||||||
// S3 API configuration.
|
// S3 API configuration.
|
||||||
Credential auth.Credentials `json:"credential"`
|
Credential auth.Credentials `json:"credential"`
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
Browser BrowserFlag `json:"browser"`
|
Browser BoolFlag `json:"browser"`
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
|
|
||||||
// Additional error logging configuration.
|
// Additional error logging configuration.
|
||||||
|
@ -552,7 +552,7 @@ type serverConfigV21 struct {
|
||||||
// S3 API configuration.
|
// S3 API configuration.
|
||||||
Credential auth.Credentials `json:"credential"`
|
Credential auth.Credentials `json:"credential"`
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
Browser BrowserFlag `json:"browser"`
|
Browser BoolFlag `json:"browser"`
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
|
|
||||||
// Notification queue configuration.
|
// Notification queue configuration.
|
||||||
|
@ -570,7 +570,7 @@ type serverConfigV22 struct {
|
||||||
// S3 API configuration.
|
// S3 API configuration.
|
||||||
Credential auth.Credentials `json:"credential"`
|
Credential auth.Credentials `json:"credential"`
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
Browser BrowserFlag `json:"browser"`
|
Browser BoolFlag `json:"browser"`
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
|
|
||||||
// Storage class configuration
|
// Storage class configuration
|
||||||
|
@ -590,7 +590,7 @@ type serverConfigV23 struct {
|
||||||
// S3 API configuration.
|
// S3 API configuration.
|
||||||
Credential auth.Credentials `json:"credential"`
|
Credential auth.Credentials `json:"credential"`
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
Browser BrowserFlag `json:"browser"`
|
Browser BoolFlag `json:"browser"`
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
|
|
||||||
// Storage class configuration
|
// Storage class configuration
|
||||||
|
@ -614,7 +614,32 @@ type serverConfigV24 struct {
|
||||||
// S3 API configuration.
|
// S3 API configuration.
|
||||||
Credential auth.Credentials `json:"credential"`
|
Credential auth.Credentials `json:"credential"`
|
||||||
Region string `json:"region"`
|
Region string `json:"region"`
|
||||||
Browser BrowserFlag `json:"browser"`
|
Browser BoolFlag `json:"browser"`
|
||||||
|
Domain string `json:"domain"`
|
||||||
|
|
||||||
|
// Storage class configuration
|
||||||
|
StorageClass storageClassConfig `json:"storageclass"`
|
||||||
|
|
||||||
|
// Cache configuration
|
||||||
|
Cache CacheConfig `json:"cache"`
|
||||||
|
|
||||||
|
// Notification queue configuration.
|
||||||
|
Notify notifier `json:"notify"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// serverConfigV25 is just like version '24', stores additionally
|
||||||
|
// worm variable.
|
||||||
|
//
|
||||||
|
// IMPORTANT NOTE: When updating this struct make sure that
|
||||||
|
// serverConfig.ConfigDiff() is updated as necessary.
|
||||||
|
type serverConfigV25 struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
|
||||||
|
// S3 API configuration.
|
||||||
|
Credential auth.Credentials `json:"credential"`
|
||||||
|
Region string `json:"region"`
|
||||||
|
Browser BoolFlag `json:"browser"`
|
||||||
|
Worm BoolFlag `json:"worm"`
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
|
|
||||||
// Storage class configuration
|
// Storage class configuration
|
||||||
|
|
|
@ -174,6 +174,7 @@ var (
|
||||||
// Set to store standard storage class
|
// Set to store standard storage class
|
||||||
globalStandardStorageClass storageClass
|
globalStandardStorageClass storageClass
|
||||||
|
|
||||||
|
globalIsEnvWORM bool
|
||||||
globalWORMEnabled bool
|
globalWORMEnabled bool
|
||||||
|
|
||||||
// Is Disk Caching set up
|
// Is Disk Caching set up
|
||||||
|
@ -217,6 +218,7 @@ func getGlobalInfo() (globalInfo map[string]interface{}) {
|
||||||
"isDistXL": globalIsDistXL,
|
"isDistXL": globalIsDistXL,
|
||||||
"isXL": globalIsXL,
|
"isXL": globalIsXL,
|
||||||
"isBrowserEnabled": globalIsBrowserEnabled,
|
"isBrowserEnabled": globalIsBrowserEnabled,
|
||||||
|
"isWorm": globalWORMEnabled,
|
||||||
"isEnvBrowser": globalIsEnvBrowser,
|
"isEnvBrowser": globalIsEnvBrowser,
|
||||||
"isEnvCreds": globalIsEnvCreds,
|
"isEnvCreds": globalIsEnvCreds,
|
||||||
"isEnvRegion": globalIsEnvRegion,
|
"isEnvRegion": globalIsEnvRegion,
|
||||||
|
|
|
@ -82,7 +82,7 @@ ENVIRONMENT VARIABLES:
|
||||||
MINIO_CACHE_DRIVES: List of mounted drives or directories delimited by ";".
|
MINIO_CACHE_DRIVES: List of mounted drives or directories delimited by ";".
|
||||||
MINIO_CACHE_EXCLUDE: List of cache exclusion patterns delimited by ";".
|
MINIO_CACHE_EXCLUDE: List of cache exclusion patterns delimited by ";".
|
||||||
MINIO_CACHE_EXPIRY: Cache expiry duration in days.
|
MINIO_CACHE_EXPIRY: Cache expiry duration in days.
|
||||||
|
|
||||||
DOMAIN:
|
DOMAIN:
|
||||||
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
|
MINIO_DOMAIN: To enable virtual-host-style requests, set this value to Minio host domain name.
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"io"
|
"io"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
@ -223,7 +222,9 @@ func registerStorageRPCRouters(router *mux.Router, endpoints EndpointList) {
|
||||||
for _, endpoint := range endpoints {
|
for _, endpoint := range endpoints {
|
||||||
if endpoint.IsLocal {
|
if endpoint.IsLocal {
|
||||||
rpcServer, err := NewStorageRPCServer(endpoint.Path)
|
rpcServer, err := NewStorageRPCServer(endpoint.Path)
|
||||||
logger.CriticalIf(context.Background(), err)
|
if err != nil {
|
||||||
|
logger.Fatal(uiErrUnableToWriteInBackend(err), "Unable to configure one of server's RPC services")
|
||||||
|
}
|
||||||
subrouter := router.PathPrefix(minioReservedBucketPath).Subrouter()
|
subrouter := router.PathPrefix(minioReservedBucketPath).Subrouter()
|
||||||
subrouter.Path(path.Join(storageServiceSubPath, endpoint.Path)).Handler(rpcServer)
|
subrouter.Path(path.Join(storageServiceSubPath, endpoint.Path)).Handler(rpcServer)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,9 @@ import (
|
||||||
// errInvalidArgument means that input argument is invalid.
|
// errInvalidArgument means that input argument is invalid.
|
||||||
var errInvalidArgument = errors.New("Invalid arguments specified")
|
var errInvalidArgument = errors.New("Invalid arguments specified")
|
||||||
|
|
||||||
|
// errMethodNotAllowed means that method is not allowed.
|
||||||
|
var errMethodNotAllowed = errors.New("Method not allowed")
|
||||||
|
|
||||||
// errSignatureMismatch means signature did not match.
|
// errSignatureMismatch means signature did not match.
|
||||||
var errSignatureMismatch = errors.New("Signature does not match")
|
var errSignatureMismatch = errors.New("Signature does not match")
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,12 @@ var (
|
||||||
"Browser can only accept `on` and `off` values. To disable web browser access, set this value to `off`",
|
"Browser can only accept `on` and `off` values. To disable web browser access, set this value to `off`",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
uiErrInvalidWormValue = newUIErrFn(
|
||||||
|
"Invalid WORM value",
|
||||||
|
"Please check the passed value",
|
||||||
|
"WORM can only accept `on` and `off` values. To enable WORM, set this value to `on`",
|
||||||
|
)
|
||||||
|
|
||||||
uiErrInvalidCacheDrivesValue = newUIErrFn(
|
uiErrInvalidCacheDrivesValue = newUIErrFn(
|
||||||
"Invalid cache drive value",
|
"Invalid cache drive value",
|
||||||
"Please check the value in this ENV variable",
|
"Please check the value in this ENV variable",
|
||||||
|
|
|
@ -353,6 +353,13 @@ next:
|
||||||
for _, objectName := range args.Objects {
|
for _, objectName := range args.Objects {
|
||||||
// If not a directory, remove the object.
|
// If not a directory, remove the object.
|
||||||
if !hasSuffix(objectName, slashSeparator) && objectName != "" {
|
if !hasSuffix(objectName, slashSeparator) && objectName != "" {
|
||||||
|
// Deny if WORM is enabled
|
||||||
|
if globalWORMEnabled {
|
||||||
|
if _, err = objectAPI.GetObjectInfo(context.Background(), args.BucketName, objectName); err == nil {
|
||||||
|
return toJSONError(errMethodNotAllowed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err = deleteObject(nil, objectAPI, web.CacheAPI(), args.BucketName, objectName, r); err != nil {
|
if err = deleteObject(nil, objectAPI, web.CacheAPI(), args.BucketName, objectName, r); err != nil {
|
||||||
break next
|
break next
|
||||||
}
|
}
|
||||||
|
@ -457,7 +464,7 @@ func (web *webAPIHandlers) SetAuth(r *http.Request, args *SetAuthArgs, reply *Se
|
||||||
}
|
}
|
||||||
|
|
||||||
// If creds are set through ENV disallow changing credentials.
|
// If creds are set through ENV disallow changing credentials.
|
||||||
if globalIsEnvCreds {
|
if globalIsEnvCreds || globalWORMEnabled {
|
||||||
return toJSONError(errChangeCredNotAllowed)
|
return toJSONError(errChangeCredNotAllowed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,6 +601,14 @@ func (web *webAPIHandlers) Upload(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deny if WORM is enabled
|
||||||
|
if globalWORMEnabled {
|
||||||
|
if _, err = objectAPI.GetObjectInfo(context.Background(), bucket, object); err == nil {
|
||||||
|
writeWebErrorResponse(w, errMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
objInfo, err := putObject(context.Background(), bucket, object, hashReader, metadata)
|
objInfo, err := putObject(context.Background(), bucket, object, hashReader, metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeWebErrorResponse(w, err)
|
writeWebErrorResponse(w, err)
|
||||||
|
@ -1103,7 +1118,10 @@ func toWebAPIError(err error) APIError {
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
Description: err.Error(),
|
Description: err.Error(),
|
||||||
}
|
}
|
||||||
|
} else if err == errMethodNotAllowed {
|
||||||
|
return getAPIError(ErrMethodNotAllowed)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert error type to api error code.
|
// Convert error type to api error code.
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case StorageFull:
|
case StorageFull:
|
||||||
|
|
|
@ -69,6 +69,18 @@ export MINIO_BROWSER=off
|
||||||
minio server /data
|
minio server /data
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Worm
|
||||||
|
|Field|Type|Description|
|
||||||
|
|:---|:---|:---|
|
||||||
|
|``worm``| _string_ | Enable this to turn on Write-Once-Read-Many. By default it is set to `off`. You may override this field with ``MINIO_WORM`` environment variable.|
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export MINIO_WORM=on
|
||||||
|
minio server /data
|
||||||
|
```
|
||||||
|
|
||||||
### Domain
|
### Domain
|
||||||
|Field|Type|Description|
|
|Field|Type|Description|
|
||||||
|:---|:---|:---|
|
|:---|:---|:---|
|
||||||
|
|
Loading…
Reference in New Issue