mirror of
https://github.com/minio/minio.git
synced 2024-12-23 21:55:53 -05:00
remove safeMode behavior in startup (#10645)
In almost all scenarios MinIO now is mostly ready for all sub-systems independently, safe-mode is not useful anymore and do not serve its original intended purpose. allow server to be fully functional even with config partially configured, this is to cater for availability of actual I/O v/s manually fixing the server. In k8s like environments it will never make sense to take pod into safe-mode state, because there is no real access to perform any remote operation on them.
This commit is contained in:
parent
1738eb24b1
commit
a0d0645128
@ -42,7 +42,7 @@ import (
|
||||
|
||||
func validateAdminReqConfigKV(ctx context.Context, w http.ResponseWriter, r *http.Request) (auth.Credentials, ObjectLayer) {
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||
return auth.Credentials{}, nil
|
||||
|
@ -35,7 +35,7 @@ func validateAdminUsersReq(ctx context.Context, w http.ResponseWriter, r *http.R
|
||||
var adminAPIErr APIErrorCode
|
||||
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||
return nil, cred
|
||||
@ -386,7 +386,7 @@ func (a adminAPIHandlers) AddServiceAccount(w http.ResponseWriter, r *http.Reque
|
||||
defer logger.AuditLog(w, r, "AddServiceAccount", mustGetClaimsFromToken(r))
|
||||
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||
return
|
||||
@ -465,7 +465,7 @@ func (a adminAPIHandlers) ListServiceAccounts(w http.ResponseWriter, r *http.Req
|
||||
defer logger.AuditLog(w, r, "ListServiceAccounts", mustGetClaimsFromToken(r))
|
||||
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||
return
|
||||
@ -520,7 +520,7 @@ func (a adminAPIHandlers) DeleteServiceAccount(w http.ResponseWriter, r *http.Re
|
||||
defer logger.AuditLog(w, r, "DeleteServiceAccount", mustGetClaimsFromToken(r))
|
||||
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||
return
|
||||
@ -579,7 +579,7 @@ func (a adminAPIHandlers) AccountUsageInfoHandler(w http.ResponseWriter, r *http
|
||||
defer logger.AuditLog(w, r, "AccountUsageInfo", mustGetClaimsFromToken(r))
|
||||
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||
return
|
||||
|
@ -899,7 +899,7 @@ func validateAdminReq(ctx context.Context, w http.ResponseWriter, r *http.Reques
|
||||
var cred auth.Credentials
|
||||
var adminAPIErr APIErrorCode
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || globalNotificationSys == nil {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||
return nil, cred
|
||||
@ -1490,11 +1490,7 @@ func (a adminAPIHandlers) ServerInfoHandler(w http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
}
|
||||
|
||||
mode := "safemode"
|
||||
if newObjectLayerFn() != nil {
|
||||
mode = "online"
|
||||
}
|
||||
|
||||
mode := "online"
|
||||
server := getLocalServerProperty(globalEndpoints, r)
|
||||
servers := globalNotificationSys.ServerInfo()
|
||||
servers = append(servers, server)
|
||||
|
@ -808,7 +808,7 @@ func (h *healSequence) traverseAndHeal() {
|
||||
func (h *healSequence) healMinioSysMeta(metaPrefix string) func() error {
|
||||
return func() error {
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -844,7 +844,7 @@ func (h *healSequence) healDiskFormat() error {
|
||||
}
|
||||
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -864,7 +864,7 @@ func (h *healSequence) healBuckets(bucketsOnly bool) error {
|
||||
}
|
||||
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -886,7 +886,7 @@ func (h *healSequence) healBuckets(bucketsOnly bool) error {
|
||||
// healBucket - traverses and heals given bucket
|
||||
func (h *healSequence) healBucket(bucket string, bucketsOnly bool) error {
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -932,7 +932,7 @@ func (h *healSequence) healBucket(bucket string, bucketsOnly bool) error {
|
||||
// healObject - heal the given object and record result
|
||||
func (h *healSequence) healObject(bucket, object, versionID string) error {
|
||||
// Get current object layer instance.
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
|
@ -703,10 +703,6 @@ func generateMultiDeleteResponse(quiet bool, deletedObjects []DeletedObject, err
|
||||
}
|
||||
|
||||
func writeResponse(w http.ResponseWriter, statusCode int, response []byte, mType mimeType) {
|
||||
if newObjectLayerFn() == nil {
|
||||
// Server still in safe mode.
|
||||
w.Header().Set(xhttp.MinIOServerStatus, "safemode")
|
||||
}
|
||||
setCommonHeaders(w)
|
||||
if mType != mimeNone {
|
||||
w.Header().Set(xhttp.ContentType, string(mType))
|
||||
@ -773,10 +769,6 @@ func writeErrorResponse(ctx context.Context, w http.ResponseWriter, err APIError
|
||||
// The request is from browser and also if browser
|
||||
// is enabled we need to redirect.
|
||||
if browser && globalBrowserEnabled {
|
||||
if newObjectLayerFn() == nil {
|
||||
// server still in safe mode.
|
||||
w.Header().Set(xhttp.MinIOServerStatus, "safemode")
|
||||
}
|
||||
w.Header().Set(xhttp.Location, minioReservedBucketPath+reqURL.Path)
|
||||
w.WriteHeader(http.StatusTemporaryRedirect)
|
||||
return
|
||||
|
@ -32,28 +32,15 @@ func newHTTPServerFn() *xhttp.Server {
|
||||
return globalHTTPServer
|
||||
}
|
||||
|
||||
func newObjectLayerWithoutSafeModeFn() ObjectLayer {
|
||||
globalObjLayerMutex.Lock()
|
||||
defer globalObjLayerMutex.Unlock()
|
||||
return globalObjectAPI
|
||||
}
|
||||
|
||||
func newObjectLayerFn() ObjectLayer {
|
||||
globalObjLayerMutex.Lock()
|
||||
defer globalObjLayerMutex.Unlock()
|
||||
if globalSafeMode {
|
||||
return nil
|
||||
}
|
||||
return globalObjectAPI
|
||||
}
|
||||
|
||||
func newCachedObjectLayerFn() CacheObjectLayer {
|
||||
globalObjLayerMutex.Lock()
|
||||
defer globalObjLayerMutex.Unlock()
|
||||
|
||||
if globalSafeMode {
|
||||
return nil
|
||||
}
|
||||
return globalCacheObjectAPI
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ func NewBucketSSEConfigSys() *BucketSSEConfigSys {
|
||||
// Get - gets bucket encryption config for the given bucket.
|
||||
func (sys *BucketSSEConfigSys) Get(bucket string) (*bucketsse.BucketSSEConfig, error) {
|
||||
if globalIsGateway {
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
return nil, errServerNotInitialized
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ type LifecycleSys struct{}
|
||||
// Get - gets lifecycle config associated to a given bucket name.
|
||||
func (sys *LifecycleSys) Get(bucketName string) (lc *lifecycle.Lifecycle, err error) {
|
||||
if globalIsGateway {
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
return nil, errServerNotInitialized
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ func (sys *BucketMetadataSys) Set(bucket string, meta BucketMetadata) {
|
||||
// Update update bucket metadata for the specified config file.
|
||||
// The configData data should not be modified after being sent here.
|
||||
func (sys *BucketMetadataSys) Update(bucket string, configFile string, configData []byte) error {
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -275,7 +275,7 @@ func (sys *BucketMetadataSys) GetLifecycleConfig(bucket string) (*lifecycle.Life
|
||||
func (sys *BucketMetadataSys) GetNotificationConfig(bucket string) (*event.Config, error) {
|
||||
if globalIsGateway && globalGatewayName == NASBackendGateway {
|
||||
// Only needed in case of NAS gateway.
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
return nil, errServerNotInitialized
|
||||
}
|
||||
@ -313,7 +313,7 @@ func (sys *BucketMetadataSys) GetSSEConfig(bucket string) (*bucketsse.BucketSSEC
|
||||
// The returned object may not be modified.
|
||||
func (sys *BucketMetadataSys) GetPolicyConfig(bucket string) (*policy.Policy, error) {
|
||||
if globalIsGateway {
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
return nil, errServerNotInitialized
|
||||
}
|
||||
@ -376,7 +376,7 @@ func (sys *BucketMetadataSys) GetBucketTargetsConfig(bucket string) (*madmin.Buc
|
||||
// GetConfig returns a specific configuration from the bucket metadata.
|
||||
// The returned object may not be modified.
|
||||
func (sys *BucketMetadataSys) GetConfig(bucket string) (BucketMetadata, error) {
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
return newBucketMetadata(bucket), errServerNotInitialized
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ type BucketObjectLockSys struct{}
|
||||
// Get - Get retention configuration.
|
||||
func (sys *BucketObjectLockSys) Get(bucketName string) (r objectlock.Retention, err error) {
|
||||
if globalIsGateway {
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
return r, errServerNotInitialized
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ func parseBucketQuota(bucket string, data []byte) (quotaCfg *madmin.BucketQuota,
|
||||
}
|
||||
|
||||
func (sys *BucketQuotaSys) check(ctx context.Context, bucket string, size int64) error {
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ import (
|
||||
// gets replication config associated to a given bucket name.
|
||||
func getReplicationConfig(ctx context.Context, bucketName string) (rc *replication.Config, err error) {
|
||||
if globalIsGateway {
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
return nil, errServerNotInitialized
|
||||
}
|
||||
|
@ -462,7 +462,7 @@ func (f *folderScanner) scanQueuedLevels(ctx context.Context, folders []cachedFo
|
||||
continue
|
||||
}
|
||||
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
continue
|
||||
}
|
||||
|
@ -300,7 +300,6 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
|
||||
|
||||
// Once endpoints are finalized, initialize the new object api in safe mode.
|
||||
globalObjLayerMutex.Lock()
|
||||
globalSafeMode = true
|
||||
globalObjectAPI = newObject
|
||||
globalObjLayerMutex.Unlock()
|
||||
|
||||
@ -325,7 +324,7 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
|
||||
|
||||
if enableIAMOps {
|
||||
// Initialize IAM sys.
|
||||
startBackgroundIAMLoad(GlobalContext)
|
||||
startBackgroundIAMLoad(GlobalContext, newObject)
|
||||
}
|
||||
|
||||
if globalCacheConfig.Enabled {
|
||||
@ -353,11 +352,6 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
|
||||
// - compression
|
||||
verifyObjectLayerFeatures("gateway "+gatewayName, newObject)
|
||||
|
||||
// Disable safe mode operation, after all initialization is over.
|
||||
globalObjLayerMutex.Lock()
|
||||
globalSafeMode = false
|
||||
globalObjLayerMutex.Unlock()
|
||||
|
||||
// Prints the formatted startup message once object layer is initialized.
|
||||
if !globalCLIContext.Quiet {
|
||||
mode := globalMinioModeGatewayPrefix + gatewayName
|
||||
|
@ -268,11 +268,6 @@ var (
|
||||
globalBackgroundHealRoutine *healRoutine
|
||||
globalBackgroundHealState *allHealState
|
||||
|
||||
// Only enabled when one of the sub-systems fail
|
||||
// to initialize, this allows for administrators to
|
||||
// fix the system.
|
||||
globalSafeMode bool
|
||||
|
||||
// If writes to FS backend should be O_SYNC.
|
||||
globalFSOSync bool
|
||||
|
||||
|
54
cmd/iam.go
54
cmd/iam.go
@ -411,8 +411,8 @@ func (sys *IAMSys) doIAMConfigMigration(ctx context.Context) error {
|
||||
// Loads IAM users and policies in background, any un-handled
|
||||
// error means this code can potentially crash the server
|
||||
// in such a situation manual intervention is necessary.
|
||||
func startBackgroundIAMLoad(ctx context.Context) {
|
||||
go globalIAMSys.Init(ctx, newObjectLayerWithoutSafeModeFn())
|
||||
func startBackgroundIAMLoad(ctx context.Context, objAPI ObjectLayer) {
|
||||
go globalIAMSys.Init(ctx, objAPI)
|
||||
}
|
||||
|
||||
// Init - initializes config system by reading entries from config/iam
|
||||
@ -514,7 +514,7 @@ func (sys *IAMSys) Init(ctx context.Context, objAPI ObjectLayer) {
|
||||
|
||||
// DeletePolicy - deletes a canned policy from backend or etcd.
|
||||
func (sys *IAMSys) DeletePolicy(policyName string) error {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -567,7 +567,7 @@ func (sys *IAMSys) DeletePolicy(policyName string) error {
|
||||
|
||||
// InfoPolicy - expands the canned policy into its JSON structure.
|
||||
func (sys *IAMSys) InfoPolicy(policyName string) (iampolicy.Policy, error) {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return iampolicy.Policy{}, errServerNotInitialized
|
||||
}
|
||||
@ -585,7 +585,7 @@ func (sys *IAMSys) InfoPolicy(policyName string) (iampolicy.Policy, error) {
|
||||
|
||||
// ListPolicies - lists all canned policies.
|
||||
func (sys *IAMSys) ListPolicies() (map[string]iampolicy.Policy, error) {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return nil, errServerNotInitialized
|
||||
}
|
||||
@ -607,7 +607,7 @@ func (sys *IAMSys) ListPolicies() (map[string]iampolicy.Policy, error) {
|
||||
|
||||
// SetPolicy - sets a new name policy.
|
||||
func (sys *IAMSys) SetPolicy(policyName string, p iampolicy.Policy) error {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -629,7 +629,7 @@ func (sys *IAMSys) SetPolicy(policyName string, p iampolicy.Policy) error {
|
||||
|
||||
// DeleteUser - delete user (only for long-term users not STS users).
|
||||
func (sys *IAMSys) DeleteUser(accessKey string) error {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -699,7 +699,7 @@ func (sys *IAMSys) currentPolicies(policyName string) string {
|
||||
|
||||
// SetTempUser - set temporary user credentials, these credentials have an expiry.
|
||||
func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyName string) error {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -749,7 +749,7 @@ func (sys *IAMSys) SetTempUser(accessKey string, cred auth.Credentials, policyNa
|
||||
|
||||
// ListUsers - list all users.
|
||||
func (sys *IAMSys) ListUsers() (map[string]madmin.UserInfo, error) {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return nil, errServerNotInitialized
|
||||
}
|
||||
@ -786,7 +786,7 @@ func (sys *IAMSys) ListUsers() (map[string]madmin.UserInfo, error) {
|
||||
|
||||
// IsTempUser - returns if given key is a temporary user.
|
||||
func (sys *IAMSys) IsTempUser(name string) (bool, error) {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return false, errServerNotInitialized
|
||||
}
|
||||
@ -804,7 +804,7 @@ func (sys *IAMSys) IsTempUser(name string) (bool, error) {
|
||||
|
||||
// IsServiceAccount - returns if given key is a service account
|
||||
func (sys *IAMSys) IsServiceAccount(name string) (bool, string, error) {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return false, "", errServerNotInitialized
|
||||
}
|
||||
@ -826,7 +826,7 @@ func (sys *IAMSys) IsServiceAccount(name string) (bool, string, error) {
|
||||
|
||||
// GetUserInfo - get info on a user.
|
||||
func (sys *IAMSys) GetUserInfo(name string) (u madmin.UserInfo, err error) {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return u, errServerNotInitialized
|
||||
}
|
||||
@ -872,7 +872,7 @@ func (sys *IAMSys) GetUserInfo(name string) (u madmin.UserInfo, err error) {
|
||||
|
||||
// SetUserStatus - sets current user status, supports disabled or enabled.
|
||||
func (sys *IAMSys) SetUserStatus(accessKey string, status madmin.AccountStatus) error {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -918,7 +918,7 @@ func (sys *IAMSys) SetUserStatus(accessKey string, status madmin.AccountStatus)
|
||||
|
||||
// NewServiceAccount - create a new service account
|
||||
func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, sessionPolicy *iampolicy.Policy) (auth.Credentials, error) {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return auth.Credentials{}, errServerNotInitialized
|
||||
}
|
||||
@ -985,7 +985,7 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, ses
|
||||
|
||||
// ListServiceAccounts - lists all services accounts associated to a specific user
|
||||
func (sys *IAMSys) ListServiceAccounts(ctx context.Context, accessKey string) ([]string, error) {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return nil, errServerNotInitialized
|
||||
}
|
||||
@ -1010,7 +1010,7 @@ func (sys *IAMSys) ListServiceAccounts(ctx context.Context, accessKey string) ([
|
||||
|
||||
// GetServiceAccountParent - gets information about a service account
|
||||
func (sys *IAMSys) GetServiceAccountParent(ctx context.Context, accessKey string) (string, error) {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return "", errServerNotInitialized
|
||||
}
|
||||
@ -1027,7 +1027,7 @@ func (sys *IAMSys) GetServiceAccountParent(ctx context.Context, accessKey string
|
||||
|
||||
// DeleteServiceAccount - delete a service account
|
||||
func (sys *IAMSys) DeleteServiceAccount(ctx context.Context, accessKey string) error {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -1056,7 +1056,7 @@ func (sys *IAMSys) DeleteServiceAccount(ctx context.Context, accessKey string) e
|
||||
|
||||
// SetUser - set user credentials and policy.
|
||||
func (sys *IAMSys) SetUser(accessKey string, uinfo madmin.UserInfo) error {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -1094,7 +1094,7 @@ func (sys *IAMSys) SetUser(accessKey string, uinfo madmin.UserInfo) error {
|
||||
|
||||
// SetUserSecretKey - sets user secret key
|
||||
func (sys *IAMSys) SetUserSecretKey(accessKey string, secretKey string) error {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -1123,7 +1123,7 @@ func (sys *IAMSys) SetUserSecretKey(accessKey string, secretKey string) error {
|
||||
|
||||
// GetUser - get user credentials
|
||||
func (sys *IAMSys) GetUser(accessKey string) (cred auth.Credentials, ok bool) {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return cred, false
|
||||
}
|
||||
@ -1187,7 +1187,7 @@ func (sys *IAMSys) GetUser(accessKey string) (cred auth.Credentials, ok bool) {
|
||||
// AddUsersToGroup - adds users to a group, creating the group if
|
||||
// needed. No error if user(s) already are in the group.
|
||||
func (sys *IAMSys) AddUsersToGroup(group string, members []string) error {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -1248,7 +1248,7 @@ func (sys *IAMSys) AddUsersToGroup(group string, members []string) error {
|
||||
// RemoveUsersFromGroup - remove users from group. If no users are
|
||||
// given, and the group is empty, deletes the group as well.
|
||||
func (sys *IAMSys) RemoveUsersFromGroup(group string, members []string) error {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -1329,7 +1329,7 @@ func (sys *IAMSys) RemoveUsersFromGroup(group string, members []string) error {
|
||||
|
||||
// SetGroupStatus - enable/disabled a group
|
||||
func (sys *IAMSys) SetGroupStatus(group string, enabled bool) error {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -1365,7 +1365,7 @@ func (sys *IAMSys) SetGroupStatus(group string, enabled bool) error {
|
||||
|
||||
// GetGroupDescription - builds up group description
|
||||
func (sys *IAMSys) GetGroupDescription(group string) (gd madmin.GroupDesc, err error) {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return gd, errServerNotInitialized
|
||||
}
|
||||
@ -1406,7 +1406,7 @@ func (sys *IAMSys) GetGroupDescription(group string) (gd madmin.GroupDesc, err e
|
||||
|
||||
// ListGroups - lists groups.
|
||||
func (sys *IAMSys) ListGroups() (r []string, err error) {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return r, errServerNotInitialized
|
||||
}
|
||||
@ -1430,7 +1430,7 @@ func (sys *IAMSys) ListGroups() (r []string, err error) {
|
||||
|
||||
// PolicyDBSet - sets a policy for a user or group in the PolicyDB.
|
||||
func (sys *IAMSys) PolicyDBSet(name, policy string, isGroup bool) error {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return errServerNotInitialized
|
||||
}
|
||||
@ -1497,7 +1497,7 @@ func (sys *IAMSys) policyDBSet(name, policyName string, userType IAMUserType, is
|
||||
// be a member of multiple groups, this function returns an array of
|
||||
// applicable policies (each group is mapped to at most one policy).
|
||||
func (sys *IAMSys) PolicyDBGet(name string, isGroup bool) ([]string, error) {
|
||||
objectAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objectAPI := newObjectLayerFn()
|
||||
if objectAPI == nil || sys == nil || sys.store == nil {
|
||||
return nil, errServerNotInitialized
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ const (
|
||||
lockMaintenanceInterval = 30 * time.Second
|
||||
|
||||
// Lock validity check interval.
|
||||
lockValidityCheckInterval = 2 * time.Minute
|
||||
lockValidityCheckInterval = 30 * time.Second
|
||||
)
|
||||
|
||||
// To abstract a node over network.
|
||||
@ -242,7 +242,7 @@ func getLongLivedLocks(interval time.Duration) map[Endpoint][]nameLockRequesterI
|
||||
//
|
||||
// We will ignore the error, and we will retry later to get a resolve on this lock
|
||||
func lockMaintenance(ctx context.Context, interval time.Duration) error {
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
return nil
|
||||
}
|
||||
@ -332,7 +332,7 @@ func startLockMaintenance(ctx context.Context) {
|
||||
// no need to start the lock maintenance
|
||||
// if ObjectAPI is not initialized.
|
||||
for {
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
|
@ -161,7 +161,7 @@ func gatewayMetricsPrometheus(ch chan<- prometheus.Metric) {
|
||||
return
|
||||
}
|
||||
|
||||
objLayer := newObjectLayerWithoutSafeModeFn()
|
||||
objLayer := newObjectLayerFn()
|
||||
// Service not initialized yet
|
||||
if objLayer == nil {
|
||||
return
|
||||
@ -372,7 +372,7 @@ func networkMetricsPrometheus(ch chan<- prometheus.Metric) {
|
||||
// Populates prometheus with bucket usage metrics, this metrics
|
||||
// is only enabled if crawler is enabled.
|
||||
func bucketUsageMetricsPrometheus(ch chan<- prometheus.Metric) {
|
||||
objLayer := newObjectLayerWithoutSafeModeFn()
|
||||
objLayer := newObjectLayerFn()
|
||||
// Service not initialized yet
|
||||
if objLayer == nil {
|
||||
return
|
||||
@ -435,7 +435,7 @@ func bucketUsageMetricsPrometheus(ch chan<- prometheus.Metric) {
|
||||
// collects storage metrics for MinIO server in Prometheus specific format
|
||||
// and sends to given channel
|
||||
func storageMetricsPrometheus(ch chan<- prometheus.Metric) {
|
||||
objLayer := newObjectLayerWithoutSafeModeFn()
|
||||
objLayer := newObjectLayerFn()
|
||||
// Service not initialized yet
|
||||
if objLayer == nil {
|
||||
return
|
||||
|
@ -613,18 +613,12 @@ func (sys *NotificationSys) Init(ctx context.Context, buckets []BucketInfo, objA
|
||||
return errServerNotInitialized
|
||||
}
|
||||
|
||||
// In gateway mode, notifications are not supported.
|
||||
// In gateway mode, notifications are not supported - except NAS gateway.
|
||||
if globalIsGateway && !objAPI.IsNotificationSupported() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if globalConfigTargetList != nil {
|
||||
for _, target := range globalConfigTargetList.Targets() {
|
||||
if err := sys.targetList.Add(target); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.LogIf(ctx, sys.targetList.Add(globalConfigTargetList.Targets()...))
|
||||
|
||||
go func() {
|
||||
for res := range sys.targetResCh {
|
||||
|
@ -64,7 +64,7 @@ func (s *peerRESTServer) DeletePolicyHandler(w http.ResponseWriter, r *http.Requ
|
||||
return
|
||||
}
|
||||
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
s.writeErrorResponse(w, errServerNotInitialized)
|
||||
return
|
||||
@ -97,7 +97,7 @@ func (s *peerRESTServer) LoadPolicyHandler(w http.ResponseWriter, r *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
s.writeErrorResponse(w, errServerNotInitialized)
|
||||
return
|
||||
@ -130,7 +130,7 @@ func (s *peerRESTServer) LoadPolicyMappingHandler(w http.ResponseWriter, r *http
|
||||
return
|
||||
}
|
||||
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
s.writeErrorResponse(w, errServerNotInitialized)
|
||||
return
|
||||
@ -164,7 +164,7 @@ func (s *peerRESTServer) DeleteServiceAccountHandler(w http.ResponseWriter, r *h
|
||||
return
|
||||
}
|
||||
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
s.writeErrorResponse(w, errServerNotInitialized)
|
||||
return
|
||||
@ -197,7 +197,7 @@ func (s *peerRESTServer) LoadServiceAccountHandler(w http.ResponseWriter, r *htt
|
||||
return
|
||||
}
|
||||
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
s.writeErrorResponse(w, errServerNotInitialized)
|
||||
return
|
||||
@ -230,7 +230,7 @@ func (s *peerRESTServer) DeleteUserHandler(w http.ResponseWriter, r *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
s.writeErrorResponse(w, errServerNotInitialized)
|
||||
return
|
||||
@ -263,7 +263,7 @@ func (s *peerRESTServer) LoadUserHandler(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
s.writeErrorResponse(w, errServerNotInitialized)
|
||||
return
|
||||
@ -307,7 +307,7 @@ func (s *peerRESTServer) LoadGroupHandler(w http.ResponseWriter, r *http.Request
|
||||
return
|
||||
}
|
||||
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
s.writeErrorResponse(w, errServerNotInitialized)
|
||||
return
|
||||
@ -609,7 +609,7 @@ func (s *peerRESTServer) LoadBucketMetadataHandler(w http.ResponseWriter, r *htt
|
||||
return
|
||||
}
|
||||
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
s.writeErrorResponse(w, errServerNotInitialized)
|
||||
return
|
||||
@ -657,7 +657,7 @@ func (s *peerRESTServer) ReloadFormatHandler(w http.ResponseWriter, r *http.Requ
|
||||
return
|
||||
}
|
||||
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
s.writeErrorResponse(w, errServerNotInitialized)
|
||||
return
|
||||
@ -767,7 +767,7 @@ func (s *peerRESTServer) GetLocalDiskIDs(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
ctx := newContext(r, w, "GetLocalDiskIDs")
|
||||
|
||||
objLayer := newObjectLayerWithoutSafeModeFn()
|
||||
objLayer := newObjectLayerFn()
|
||||
|
||||
// Service not initialized yet
|
||||
if objLayer == nil {
|
||||
|
@ -186,7 +186,7 @@ func newAllSubsystems() {
|
||||
globalBucketTargetSys = NewBucketTargetSys()
|
||||
}
|
||||
|
||||
func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) {
|
||||
func initServer(ctx context.Context, newObject ObjectLayer) (err error) {
|
||||
// Create cancel context to control 'newRetryTimer' go routine.
|
||||
retryCtx, cancel := context.WithCancel(ctx)
|
||||
|
||||
@ -199,33 +199,33 @@ func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) {
|
||||
// appropriately. This is also true for rotation of encrypted
|
||||
// content.
|
||||
txnLk := newObject.NewNSLock(retryCtx, minioMetaBucket, minioConfigPrefix+"/transaction.lock")
|
||||
var locked bool
|
||||
defer func(txnLk RWLocker) {
|
||||
if locked {
|
||||
txnLk.Unlock()
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
var cerr config.Err
|
||||
// For any config error, we don't need to drop into safe-mode
|
||||
// instead its a user error and should be fixed by user.
|
||||
if errors.As(err, &cerr) {
|
||||
logger.FatalIf(err, "Unable to initialize the server")
|
||||
return
|
||||
}
|
||||
|
||||
// If context was canceled
|
||||
if errors.Is(err, context.Canceled) {
|
||||
logger.FatalIf(err, "Server startup canceled upon user request")
|
||||
return
|
||||
}
|
||||
|
||||
// Prints the formatted startup message in safe mode operation.
|
||||
// Drops-into safe mode where users need to now manually recover
|
||||
// the server.
|
||||
printStartupSafeModeMessage(getAPIEndpoints(), err)
|
||||
|
||||
<-globalOSSignalCh
|
||||
}
|
||||
}(txnLk)
|
||||
|
||||
// Prints the formatted startup message, if err is not nil then it prints additional information as well.
|
||||
printStartupMessage(getAPIEndpoints(), err)
|
||||
|
||||
if globalActiveCred.Equal(auth.DefaultCredentials) {
|
||||
msg := fmt.Sprintf("Detected default credentials '%s', please change the credentials immediately using 'MINIO_ACCESS_KEY' and 'MINIO_SECRET_KEY'", globalActiveCred)
|
||||
logger.StartupMessage(color.RedBold(msg))
|
||||
}
|
||||
|
||||
<-globalOSSignalCh
|
||||
}()
|
||||
|
||||
// Enable background operations for erasure coding
|
||||
if globalIsErasure {
|
||||
@ -256,9 +256,6 @@ func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) {
|
||||
continue
|
||||
}
|
||||
|
||||
// locked successful
|
||||
locked = true
|
||||
|
||||
// These messages only meant primarily for distributed setup, so only log during distributed setup.
|
||||
if globalIsDistErasure {
|
||||
logger.Info("Waiting for all MinIO sub-systems to be initialized.. lock acquired")
|
||||
@ -270,7 +267,8 @@ func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) {
|
||||
if err = handleEncryptedConfigBackend(newObject); err == nil {
|
||||
// Upon success migrating the config, initialize all sub-systems
|
||||
// if all sub-systems initialized successfully return right away
|
||||
if err = initAllSubsystems(retryCtx, newObject); err == nil {
|
||||
if err = initAllSubsystems(ctx, newObject); err == nil {
|
||||
txnLk.Unlock()
|
||||
// All successful return.
|
||||
if globalIsDistErasure {
|
||||
// These messages only meant primarily for distributed setup, so only log during distributed setup.
|
||||
@ -280,6 +278,8 @@ func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
txnLk.Unlock() // Unlock the transaction lock and allow other nodes to acquire the lock if possible.
|
||||
|
||||
// One of these retriable errors shall be retried.
|
||||
if errors.Is(err, errDiskNotFound) ||
|
||||
errors.Is(err, errConfigNotFound) ||
|
||||
@ -288,8 +288,6 @@ func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) {
|
||||
errors.As(err, &wquorum) ||
|
||||
isErrBucketNotFound(err) {
|
||||
logger.Info("Waiting for all MinIO sub-systems to be initialized.. possible cause (%v)", err)
|
||||
txnLk.Unlock() // Unlock the transaction lock and allow other nodes to acquire the lock if possible.
|
||||
locked = false
|
||||
continue
|
||||
}
|
||||
|
||||
@ -299,7 +297,7 @@ func initSafeMode(ctx context.Context, newObject ObjectLayer) (err error) {
|
||||
|
||||
// Return an error when retry is canceled or deadlined
|
||||
if err = retryCtx.Err(); err != nil {
|
||||
return fmt.Errorf("Unable to initialize sub-systems: %w", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Retry was canceled successfully.
|
||||
@ -314,13 +312,13 @@ func initAllSubsystems(ctx context.Context, newObject ObjectLayer) (err error) {
|
||||
// ensures top level retry works accordingly.
|
||||
// List buckets to heal, and be re-used for loading configs.
|
||||
var buckets []BucketInfo
|
||||
rquorum := InsufficientReadQuorum{}
|
||||
wquorum := InsufficientWriteQuorum{}
|
||||
if globalIsErasure {
|
||||
buckets, err = newObject.ListBucketsHeal(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to list buckets to heal: %w", err)
|
||||
}
|
||||
rquorum := InsufficientReadQuorum{}
|
||||
wquorum := InsufficientWriteQuorum{}
|
||||
for _, bucket := range buckets {
|
||||
if err = newObject.MakeBucketWithLocation(ctx, bucket.Name, BucketOptions{}); err != nil {
|
||||
if errors.As(err, &wquorum) || errors.As(err, &rquorum) {
|
||||
@ -344,7 +342,16 @@ func initAllSubsystems(ctx context.Context, newObject ObjectLayer) (err error) {
|
||||
|
||||
// Initialize config system.
|
||||
if err = globalConfigSys.Init(newObject); err != nil {
|
||||
return fmt.Errorf("Unable to initialize config system: %w", err)
|
||||
if errors.Is(err, errDiskNotFound) ||
|
||||
errors.Is(err, errConfigNotFound) ||
|
||||
errors.Is(err, context.DeadlineExceeded) ||
|
||||
errors.As(err, &rquorum) ||
|
||||
errors.As(err, &wquorum) ||
|
||||
isErrBucketNotFound(err) {
|
||||
return fmt.Errorf("Unable to initialize config system: %w", err)
|
||||
}
|
||||
// Any other config errors we simply print a message and proceed forward.
|
||||
logger.LogIf(ctx, err)
|
||||
}
|
||||
|
||||
// Populate existing buckets to the etcd backend
|
||||
@ -353,20 +360,25 @@ func initAllSubsystems(ctx context.Context, newObject ObjectLayer) (err error) {
|
||||
go initFederatorBackend(buckets, newObject)
|
||||
}
|
||||
|
||||
// Initialize bucket metadata sub-system.
|
||||
if err = globalBucketMetadataSys.Init(ctx, buckets, newObject); err != nil {
|
||||
return fmt.Errorf("Unable to initialize bucket metadata sub-system: %w", err)
|
||||
if globalCacheConfig.Enabled {
|
||||
// initialize the new disk cache objects.
|
||||
var cacheAPI CacheObjectLayer
|
||||
cacheAPI, err = newServerCacheObjects(ctx, globalCacheConfig)
|
||||
logger.FatalIf(err, "Unable to initialize disk caching")
|
||||
|
||||
globalObjLayerMutex.Lock()
|
||||
globalCacheObjectAPI = cacheAPI
|
||||
globalObjLayerMutex.Unlock()
|
||||
}
|
||||
|
||||
// Initialize bucket metadata sub-system.
|
||||
globalBucketMetadataSys.Init(ctx, buckets, newObject)
|
||||
|
||||
// Initialize notification system.
|
||||
if err = globalNotificationSys.Init(ctx, buckets, newObject); err != nil {
|
||||
return fmt.Errorf("Unable to initialize notification system: %w", err)
|
||||
}
|
||||
globalNotificationSys.Init(ctx, buckets, newObject)
|
||||
|
||||
// Initialize bucket targets sub-system.
|
||||
if err = globalBucketTargetSys.Init(ctx, buckets, newObject); err != nil {
|
||||
return fmt.Errorf("Unable to initialize bucket target sub-system: %w", err)
|
||||
}
|
||||
globalBucketTargetSys.Init(ctx, buckets, newObject)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -488,42 +500,15 @@ func serverMain(ctx *cli.Context) {
|
||||
|
||||
// Once endpoints are finalized, initialize the new object api in safe mode.
|
||||
globalObjLayerMutex.Lock()
|
||||
globalSafeMode = true
|
||||
globalObjectAPI = newObject
|
||||
globalObjLayerMutex.Unlock()
|
||||
|
||||
go initDataCrawler(GlobalContext, newObject)
|
||||
|
||||
logger.FatalIf(initSafeMode(GlobalContext, newObject), "Unable to initialize server switching into safe-mode")
|
||||
|
||||
// Initialize users credentials and policies in background.
|
||||
go startBackgroundIAMLoad(GlobalContext)
|
||||
go startBackgroundIAMLoad(GlobalContext, newObject)
|
||||
|
||||
if globalCacheConfig.Enabled {
|
||||
// initialize the new disk cache objects.
|
||||
var cacheAPI CacheObjectLayer
|
||||
cacheAPI, err = newServerCacheObjects(GlobalContext, globalCacheConfig)
|
||||
logger.FatalIf(err, "Unable to initialize disk caching")
|
||||
|
||||
globalObjLayerMutex.Lock()
|
||||
globalCacheObjectAPI = cacheAPI
|
||||
globalObjLayerMutex.Unlock()
|
||||
}
|
||||
|
||||
// Disable safe mode operation, after all initialization is over.
|
||||
globalObjLayerMutex.Lock()
|
||||
globalSafeMode = false
|
||||
globalObjLayerMutex.Unlock()
|
||||
|
||||
// Prints the formatted startup message once object layer is initialized.
|
||||
printStartupMessage(getAPIEndpoints())
|
||||
|
||||
if globalActiveCred.Equal(auth.DefaultCredentials) {
|
||||
msg := fmt.Sprintf("Detected default credentials '%s', please change the credentials immediately using 'MINIO_ACCESS_KEY' and 'MINIO_SECRET_KEY'", globalActiveCred)
|
||||
logger.StartupMessage(color.RedBold(msg))
|
||||
}
|
||||
|
||||
<-globalOSSignalCh
|
||||
initServer(GlobalContext, newObject)
|
||||
}
|
||||
|
||||
// Initialize object layer with the supplied disks, objectLayer is nil upon any error.
|
||||
|
@ -32,13 +32,12 @@ import (
|
||||
|
||||
// Documentation links, these are part of message printing code.
|
||||
const (
|
||||
mcQuickStartGuide = "https://docs.min.io/docs/minio-client-quickstart-guide"
|
||||
mcAdminQuickStartGuide = "https://docs.min.io/docs/minio-admin-complete-guide.html"
|
||||
goQuickStartGuide = "https://docs.min.io/docs/golang-client-quickstart-guide"
|
||||
jsQuickStartGuide = "https://docs.min.io/docs/javascript-client-quickstart-guide"
|
||||
javaQuickStartGuide = "https://docs.min.io/docs/java-client-quickstart-guide"
|
||||
pyQuickStartGuide = "https://docs.min.io/docs/python-client-quickstart-guide"
|
||||
dotnetQuickStartGuide = "https://docs.min.io/docs/dotnet-client-quickstart-guide"
|
||||
mcQuickStartGuide = "https://docs.min.io/docs/minio-client-quickstart-guide"
|
||||
goQuickStartGuide = "https://docs.min.io/docs/golang-client-quickstart-guide"
|
||||
jsQuickStartGuide = "https://docs.min.io/docs/javascript-client-quickstart-guide"
|
||||
javaQuickStartGuide = "https://docs.min.io/docs/java-client-quickstart-guide"
|
||||
pyQuickStartGuide = "https://docs.min.io/docs/python-client-quickstart-guide"
|
||||
dotnetQuickStartGuide = "https://docs.min.io/docs/dotnet-client-quickstart-guide"
|
||||
)
|
||||
|
||||
// generates format string depending on the string length and padding.
|
||||
@ -52,65 +51,13 @@ func mustGetStorageInfo(objAPI ObjectLayer) StorageInfo {
|
||||
return storageInfo
|
||||
}
|
||||
|
||||
func printStartupSafeModeMessage(apiEndpoints []string, err error) {
|
||||
logStartupMessage(color.RedBold("Server startup failed with '%v'", err))
|
||||
logStartupMessage(color.RedBold("Server switching to safe mode"))
|
||||
logStartupMessage(color.RedBold("Please use 'mc admin config' commands fix this issue"))
|
||||
|
||||
// Object layer is initialized then print StorageInfo in safe mode.
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
if objAPI != nil {
|
||||
if msg := getStorageInfoMsgSafeMode(mustGetStorageInfo(objAPI)); msg != "" {
|
||||
logStartupMessage(msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Get saved credentials.
|
||||
cred := globalActiveCred
|
||||
|
||||
// Get saved region.
|
||||
region := globalServerRegion
|
||||
|
||||
strippedAPIEndpoints := stripStandardPorts(apiEndpoints)
|
||||
|
||||
apiEndpointStr := strings.Join(strippedAPIEndpoints, " ")
|
||||
|
||||
// Colorize the message and print.
|
||||
logStartupMessage(color.Red("Endpoint: ") + color.Bold(fmt.Sprintf(getFormatStr(len(apiEndpointStr), 1), apiEndpointStr)))
|
||||
if color.IsTerminal() && !globalCLIContext.Anonymous {
|
||||
logStartupMessage(color.Red("AccessKey: ") + color.Bold(fmt.Sprintf("%s ", cred.AccessKey)))
|
||||
logStartupMessage(color.Red("SecretKey: ") + color.Bold(fmt.Sprintf("%s ", cred.SecretKey)))
|
||||
if region != "" {
|
||||
logStartupMessage(color.Red("Region: ") + color.Bold(fmt.Sprintf(getFormatStr(len(region), 3), region)))
|
||||
}
|
||||
}
|
||||
|
||||
// Prints `mc` cli configuration message chooses
|
||||
// first endpoint as default.
|
||||
alias := "myminio"
|
||||
endPoint := strippedAPIEndpoints[0]
|
||||
|
||||
// Configure 'mc', following block prints platform specific information for minio client admin commands.
|
||||
if color.IsTerminal() && !globalCLIContext.Anonymous {
|
||||
logStartupMessage(color.RedBold("\nCommand-line Access: ") + mcAdminQuickStartGuide)
|
||||
if runtime.GOOS == globalWindowsOSName {
|
||||
mcMessage := fmt.Sprintf("> mc.exe alias set %s %s %s %s --api s3v4", alias,
|
||||
endPoint, cred.AccessKey, cred.SecretKey)
|
||||
logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage))
|
||||
mcMessage = "> mc.exe admin config --help"
|
||||
logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage))
|
||||
} else {
|
||||
mcMessage := fmt.Sprintf("$ mc alias set %s %s %s %s --api s3v4", alias,
|
||||
endPoint, cred.AccessKey, cred.SecretKey)
|
||||
logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage))
|
||||
mcMessage = "$ mc admin config --help"
|
||||
logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prints the formatted startup message.
|
||||
func printStartupMessage(apiEndpoints []string) {
|
||||
func printStartupMessage(apiEndpoints []string, err error) {
|
||||
if err != nil {
|
||||
logStartupMessage(color.RedBold("Server startup failed with '%v'", err))
|
||||
logStartupMessage(color.RedBold("Not all features may be available on this server"))
|
||||
logStartupMessage(color.RedBold("Please use 'mc admin' commands to further investigate this issue"))
|
||||
}
|
||||
|
||||
strippedAPIEndpoints := stripStandardPorts(apiEndpoints)
|
||||
// If cache layer is enabled, print cache capacity.
|
||||
@ -254,23 +201,6 @@ func printObjectAPIMsg() {
|
||||
logStartupMessage(color.Blue(" .NET: ") + fmt.Sprintf(getFormatStr(len(dotnetQuickStartGuide), 6), dotnetQuickStartGuide))
|
||||
}
|
||||
|
||||
// Get formatted disk/storage info message.
|
||||
func getStorageInfoMsgSafeMode(storageInfo StorageInfo) string {
|
||||
var msg string
|
||||
var mcMessage string
|
||||
if storageInfo.Backend.Type == BackendErasure {
|
||||
if storageInfo.Backend.OfflineDisks.Sum() > 0 {
|
||||
mcMessage = "Use `mc admin info` to look for latest server/disk info\n"
|
||||
}
|
||||
diskInfo := fmt.Sprintf(" %d Online, %d Offline. ", storageInfo.Backend.OnlineDisks.Sum(), storageInfo.Backend.OfflineDisks.Sum())
|
||||
msg += color.Red("Status:") + fmt.Sprintf(getFormatStr(len(diskInfo), 8), diskInfo)
|
||||
}
|
||||
if len(mcMessage) > 0 {
|
||||
msg = fmt.Sprintf("%s %s", mcMessage, msg)
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
// Get formatted disk/storage info message.
|
||||
func getStorageInfoMsg(storageInfo StorageInfo) string {
|
||||
var msg string
|
||||
|
@ -102,5 +102,5 @@ func TestPrintStartupMessage(t *testing.T) {
|
||||
}
|
||||
|
||||
apiEndpoints := []string{"http://127.0.0.1:9000"}
|
||||
printStartupMessage(apiEndpoints)
|
||||
printStartupMessage(apiEndpoints, nil)
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ func handleSignals() {
|
||||
}
|
||||
}
|
||||
|
||||
if objAPI := newObjectLayerWithoutSafeModeFn(); objAPI != nil {
|
||||
if objAPI := newObjectLayerFn(); objAPI != nil {
|
||||
oerr = objAPI.Shutdown(context.Background())
|
||||
logger.LogIf(context.Background(), oerr)
|
||||
}
|
||||
|
@ -2077,16 +2077,10 @@ func registerAPIFunctions(muxRouter *mux.Router, objLayer ObjectLayer, apiFuncti
|
||||
// operation
|
||||
api := objectAPIHandlers{
|
||||
ObjectAPI: func() ObjectLayer {
|
||||
if !globalSafeMode {
|
||||
return globalObjectAPI
|
||||
}
|
||||
return nil
|
||||
return globalObjectAPI
|
||||
},
|
||||
CacheAPI: func() CacheObjectLayer {
|
||||
if !globalSafeMode {
|
||||
return globalCacheObjectAPI
|
||||
}
|
||||
return nil
|
||||
return globalCacheObjectAPI
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -366,7 +366,7 @@ func (s *xlStorage) CrawlAndGetDataUsage(ctx context.Context, cache dataUsageCac
|
||||
}
|
||||
|
||||
// Get object api
|
||||
objAPI := newObjectLayerWithoutSafeModeFn()
|
||||
objAPI := newObjectLayerFn()
|
||||
if objAPI == nil {
|
||||
return cache, errServerNotInitialized
|
||||
}
|
||||
|
@ -86,6 +86,10 @@ func (list *TargetList) Remove(targetIDSet TargetIDSet) {
|
||||
|
||||
// Targets - list all targets
|
||||
func (list *TargetList) Targets() []Target {
|
||||
if list == nil {
|
||||
return []Target{}
|
||||
}
|
||||
|
||||
list.RLock()
|
||||
defer list.RUnlock()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user