mirror of
https://github.com/minio/minio.git
synced 2024-12-25 14:45:54 -05:00
Cleanup ui-errors and print proper error messages (#8068)
* Cleanup ui-errors and print proper error messages Change HELP to HINT instead, handle more error cases when starting up MinIO. One such is related to #8048 * Apply suggestions from code review
This commit is contained in:
parent
8ce424bacd
commit
bf8ec8ad73
@ -61,6 +61,9 @@ func verifyObjectLayerFeatures(name string, objAPI ObjectLayer) {
|
|||||||
func checkUpdate(mode string) {
|
func checkUpdate(mode string) {
|
||||||
// Its OK to ignore any errors during doUpdate() here.
|
// Its OK to ignore any errors during doUpdate() here.
|
||||||
if updateMsg, _, currentReleaseTime, latestReleaseTime, err := getUpdateInfo(2*time.Second, mode); err == nil {
|
if updateMsg, _, currentReleaseTime, latestReleaseTime, err := getUpdateInfo(2*time.Second, mode); err == nil {
|
||||||
|
if updateMsg == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
if globalInplaceUpdateDisabled {
|
if globalInplaceUpdateDisabled {
|
||||||
logger.StartupMessage(updateMsg)
|
logger.StartupMessage(updateMsg)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* MinIO Cloud Storage, (C) 2015, 2016, 2017, 2018 MinIO, Inc.
|
* MinIO Cloud Storage, (C) 2015-2019 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.
|
||||||
@ -377,7 +377,7 @@ func serverMain(ctx *cli.Context) {
|
|||||||
|
|
||||||
// Initialize notification system.
|
// Initialize notification system.
|
||||||
if err = globalNotificationSys.Init(newObject); err != nil {
|
if err = globalNotificationSys.Init(newObject); err != nil {
|
||||||
logger.LogIf(context.Background(), err)
|
logger.Fatal(err, "Unable to initialize notification system")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify if object layer supports
|
// Verify if object layer supports
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* MinIO Cloud Storage, (C) 2015, 2016, 2017, 2018 MinIO, Inc.
|
* MinIO Cloud Storage, (C) 2015-2019 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.
|
||||||
@ -26,13 +26,13 @@ import (
|
|||||||
|
|
||||||
func handleSignals() {
|
func handleSignals() {
|
||||||
// Custom exit function
|
// Custom exit function
|
||||||
exit := func(state bool) {
|
exit := func(success bool) {
|
||||||
// If global profiler is set stop before we exit.
|
// If global profiler is set stop before we exit.
|
||||||
if globalProfiler != nil {
|
if globalProfiler != nil {
|
||||||
globalProfiler.Stop()
|
globalProfiler.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
if state {
|
if success {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,13 +66,13 @@ func handleSignals() {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case err := <-globalHTTPServerErrorCh:
|
case err := <-globalHTTPServerErrorCh:
|
||||||
logger.LogIf(context.Background(), err)
|
|
||||||
var oerr error
|
|
||||||
if objAPI := newObjectLayerFn(); objAPI != nil {
|
if objAPI := newObjectLayerFn(); objAPI != nil {
|
||||||
oerr = objAPI.Shutdown(context.Background())
|
objAPI.Shutdown(context.Background())
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
exit(err == nil && oerr == nil)
|
logger.Fatal(err, "Unable to start MinIO server")
|
||||||
|
}
|
||||||
|
exit(true)
|
||||||
case osSignal := <-globalOSSignalCh:
|
case osSignal := <-globalOSSignalCh:
|
||||||
logger.Info("Exiting on signal: %s", strings.ToUpper(osSignal.String()))
|
logger.Info("Exiting on signal: %s", strings.ToUpper(osSignal.String()))
|
||||||
exit(stopProcess())
|
exit(stopProcess())
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* MinIO Cloud Storage, (C) 2018 MinIO, Inc.
|
* MinIO Cloud Storage, (C) 2018-2019 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,6 +21,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
// uiErr is a structure which contains all information
|
// uiErr is a structure which contains all information
|
||||||
@ -30,7 +31,7 @@ type uiErr struct {
|
|||||||
msg string
|
msg string
|
||||||
detail string
|
detail string
|
||||||
action string
|
action string
|
||||||
help string
|
hint string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the error message
|
// Return the error message
|
||||||
@ -47,7 +48,7 @@ func (u uiErr) Msg(m string, args ...interface{}) uiErr {
|
|||||||
msg: fmt.Sprintf(m, args...),
|
msg: fmt.Sprintf(m, args...),
|
||||||
detail: u.detail,
|
detail: u.detail,
|
||||||
action: u.action,
|
action: u.action,
|
||||||
help: u.help,
|
hint: u.hint,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,12 +57,12 @@ type uiErrFn func(err error) uiErr
|
|||||||
// Create a UI error generator, this is needed to simplify
|
// Create a UI error generator, this is needed to simplify
|
||||||
// the update of the detailed error message in several places
|
// the update of the detailed error message in several places
|
||||||
// in MinIO code
|
// in MinIO code
|
||||||
func newUIErrFn(msg, action, help string) uiErrFn {
|
func newUIErrFn(msg, action, hint string) uiErrFn {
|
||||||
return func(err error) uiErr {
|
return func(err error) uiErr {
|
||||||
u := uiErr{
|
u := uiErr{
|
||||||
msg: msg,
|
msg: msg,
|
||||||
action: action,
|
action: action,
|
||||||
help: help,
|
hint: hint,
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
u.detail = err.Error()
|
u.detail = err.Error()
|
||||||
@ -82,8 +83,13 @@ func errorToUIErr(err error) uiErr {
|
|||||||
switch e := err.(type) {
|
switch e := err.(type) {
|
||||||
case *net.OpError:
|
case *net.OpError:
|
||||||
if e.Op == "listen" {
|
if e.Op == "listen" {
|
||||||
return uiErrPortAlreadyInUse(e).Msg("Port " + e.Addr.String() + " is already in use")
|
if oe, ok := e.Err.(*os.SyscallError); ok {
|
||||||
|
if oe.Err == syscall.EADDRINUSE {
|
||||||
|
return uiErrPortAlreadyInUse(e).Msg("Specified port '" + e.Addr.String() + "' is already in use")
|
||||||
|
} else if oe.Err == syscall.EACCES {
|
||||||
|
return uiErrPortAccess(e).Msg("Insufficient permissions to use specified port '" + e.Addr.String() + "'")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case *os.PathError:
|
case *os.PathError:
|
||||||
if os.IsPermission(e) {
|
if os.IsPermission(e) {
|
||||||
@ -117,19 +123,19 @@ func fmtError(introMsg string, err error, jsonFlag bool) string {
|
|||||||
// Pretty print error message
|
// Pretty print error message
|
||||||
introMsg += ": "
|
introMsg += ": "
|
||||||
if uiErr.msg != "" {
|
if uiErr.msg != "" {
|
||||||
introMsg += colorBold(uiErr.msg + ".")
|
introMsg += colorBold(uiErr.msg)
|
||||||
} else {
|
} else {
|
||||||
introMsg += colorBold(err.Error() + ".")
|
introMsg += colorBold(err.Error())
|
||||||
}
|
}
|
||||||
renderedTxt += colorRed(introMsg) + "\n"
|
renderedTxt += colorRed(introMsg) + "\n"
|
||||||
// Add action message
|
// Add action message
|
||||||
if uiErr.action != "" {
|
if uiErr.action != "" {
|
||||||
renderedTxt += "> " + colorBgYellow(colorBlack(uiErr.action+".")) + "\n"
|
renderedTxt += "> " + colorBgYellow(colorBlack(uiErr.action)) + "\n"
|
||||||
}
|
}
|
||||||
// Add help
|
// Add hint
|
||||||
if uiErr.help != "" {
|
if uiErr.hint != "" {
|
||||||
renderedTxt += colorBold("HELP:") + "\n"
|
renderedTxt += colorBold("HINT:") + "\n"
|
||||||
renderedTxt += " " + uiErr.help
|
renderedTxt += " " + uiErr.hint
|
||||||
}
|
}
|
||||||
return renderedTxt
|
return renderedTxt
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* MinIO Cloud Storage, (C) 2018 MinIO, Inc.
|
* MinIO Cloud Storage, (C) 2018-2019 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.
|
||||||
@ -32,13 +32,13 @@ var (
|
|||||||
uiErrInvalidDomainValue = newUIErrFn(
|
uiErrInvalidDomainValue = newUIErrFn(
|
||||||
"Invalid domain value",
|
"Invalid domain value",
|
||||||
"Please check the passed value",
|
"Please check the passed value",
|
||||||
"Domain can only accept DNS compatible values.",
|
"Domain can only accept DNS compatible values",
|
||||||
)
|
)
|
||||||
|
|
||||||
uiErrInvalidErasureSetSize = newUIErrFn(
|
uiErrInvalidErasureSetSize = newUIErrFn(
|
||||||
"Invalid erasure set size",
|
"Invalid erasure set size",
|
||||||
"Please check the passed value",
|
"Please check the passed value",
|
||||||
"Erasure set can only accept any of [4, 6, 8, 10, 12, 14, 16] values.",
|
"Erasure set can only accept any of [4, 6, 8, 10, 12, 14, 16] values",
|
||||||
)
|
)
|
||||||
|
|
||||||
uiErrInvalidWormValue = newUIErrFn(
|
uiErrInvalidWormValue = newUIErrFn(
|
||||||
@ -62,32 +62,32 @@ var (
|
|||||||
uiErrInvalidCacheExpiryValue = newUIErrFn(
|
uiErrInvalidCacheExpiryValue = newUIErrFn(
|
||||||
"Invalid cache expiry value",
|
"Invalid cache expiry value",
|
||||||
"Please check the passed value",
|
"Please check the passed value",
|
||||||
"MINIO_CACHE_EXPIRY: Valid cache expiry duration is in days.",
|
"MINIO_CACHE_EXPIRY: Valid cache expiry duration is in days",
|
||||||
)
|
)
|
||||||
|
|
||||||
uiErrInvalidCacheMaxUse = newUIErrFn(
|
uiErrInvalidCacheMaxUse = newUIErrFn(
|
||||||
"Invalid cache max-use value",
|
"Invalid cache max-use value",
|
||||||
"Please check the passed value",
|
"Please check the passed value",
|
||||||
"MINIO_CACHE_MAXUSE: Valid cache max-use value between 0-100.",
|
"MINIO_CACHE_MAXUSE: Valid cache max-use value between 0-100",
|
||||||
)
|
)
|
||||||
|
|
||||||
uiErrInvalidCredentials = newUIErrFn(
|
uiErrInvalidCredentials = newUIErrFn(
|
||||||
"Invalid credentials",
|
"Invalid credentials",
|
||||||
"Please provide correct credentials",
|
"Please provide correct credentials",
|
||||||
`Access key length should be between minimum 3 characters in length.
|
`Access key length should be between minimum 3 characters in length.
|
||||||
Secret key should be in between 8 and 40 characters.`,
|
Secret key should be in between 8 and 40 characters`,
|
||||||
)
|
)
|
||||||
|
|
||||||
uiErrEnvCredentialsMissingGateway = newUIErrFn(
|
uiErrEnvCredentialsMissingGateway = newUIErrFn(
|
||||||
"Credentials missing",
|
"Credentials missing",
|
||||||
"Please set your credentials in the environment",
|
"Please set your credentials in the environment",
|
||||||
`In Gateway mode, access and secret keys should be specified via environment variables MINIO_ACCESS_KEY and MINIO_SECRET_KEY respectively.`,
|
`In Gateway mode, access and secret keys should be specified via environment variables MINIO_ACCESS_KEY and MINIO_SECRET_KEY respectively`,
|
||||||
)
|
)
|
||||||
|
|
||||||
uiErrEnvCredentialsMissingDistributed = newUIErrFn(
|
uiErrEnvCredentialsMissingDistributed = newUIErrFn(
|
||||||
"Credentials missing",
|
"Credentials missing",
|
||||||
"Please set your credentials in the environment",
|
"Please set your credentials in the environment",
|
||||||
`In distributed server mode, access and secret keys should be specified via environment variables MINIO_ACCESS_KEY and MINIO_SECRET_KEY respectively.`,
|
`In distributed server mode, access and secret keys should be specified via environment variables MINIO_ACCESS_KEY and MINIO_SECRET_KEY respectively`,
|
||||||
)
|
)
|
||||||
|
|
||||||
uiErrInvalidErasureEndpoints = newUIErrFn(
|
uiErrInvalidErasureEndpoints = newUIErrFn(
|
||||||
@ -105,9 +105,9 @@ Secret key should be in between 8 and 40 characters.`,
|
|||||||
uiErrStorageClassValue = newUIErrFn(
|
uiErrStorageClassValue = newUIErrFn(
|
||||||
"Invalid storage class value",
|
"Invalid storage class value",
|
||||||
"Please check the value",
|
"Please check the value",
|
||||||
`MINIO_STORAGE_CLASS_STANDARD: Format "EC:<Default_Parity_Standard_Class>" (e.g. "EC:3"). This sets the number of parity disks for MinIO server in Standard mode. Objects are stored in Standard mode, if storage class is not defined in Put request.
|
`MINIO_STORAGE_CLASS_STANDARD: Format "EC:<Default_Parity_Standard_Class>" (e.g. "EC:3"). This sets the number of parity disks for MinIO server in Standard mode. Objects are stored in Standard mode, if storage class is not defined in Put request
|
||||||
MINIO_STORAGE_CLASS_RRS: Format "EC:<Default_Parity_Reduced_Redundancy_Class>" (e.g. "EC:3"). This sets the number of parity disks for MinIO server in Reduced Redundancy mode. Objects are stored in Reduced Redundancy mode, if Put request specifies RRS storage class.
|
MINIO_STORAGE_CLASS_RRS: Format "EC:<Default_Parity_Reduced_Redundancy_Class>" (e.g. "EC:3"). This sets the number of parity disks for MinIO server in Reduced Redundancy mode. Objects are stored in Reduced Redundancy mode, if Put request specifies RRS storage class
|
||||||
Refer to the link https://github.com/minio/minio/tree/master/docs/erasure/storage-class for more information.`,
|
Refer to the link https://github.com/minio/minio/tree/master/docs/erasure/storage-class for more information`,
|
||||||
)
|
)
|
||||||
|
|
||||||
uiErrUnexpectedBackendVersion = newUIErrFn(
|
uiErrUnexpectedBackendVersion = newUIErrFn(
|
||||||
@ -128,7 +128,7 @@ Refer to the link https://github.com/minio/minio/tree/master/docs/erasure/storag
|
|||||||
uiErrInvalidFSEndpoint = newUIErrFn(
|
uiErrInvalidFSEndpoint = newUIErrFn(
|
||||||
"Invalid endpoint for standalone FS mode",
|
"Invalid endpoint for standalone FS mode",
|
||||||
"Please check the FS endpoint",
|
"Please check the FS endpoint",
|
||||||
`FS mode requires only one writable disk path.
|
`FS mode requires only one writable disk path
|
||||||
Example 1:
|
Example 1:
|
||||||
$ minio server /data/minio/`,
|
$ minio server /data/minio/`,
|
||||||
)
|
)
|
||||||
@ -136,7 +136,7 @@ Example 1:
|
|||||||
uiErrUnableToWriteInBackend = newUIErrFn(
|
uiErrUnableToWriteInBackend = newUIErrFn(
|
||||||
"Unable to write to the backend",
|
"Unable to write to the backend",
|
||||||
"Please ensure MinIO binary has write permissions for the backend",
|
"Please ensure MinIO binary has write permissions for the backend",
|
||||||
"",
|
`Verify if MinIO binary is running as the same user who has write permissions for the backend`,
|
||||||
)
|
)
|
||||||
|
|
||||||
uiErrPortAlreadyInUse = newUIErrFn(
|
uiErrPortAlreadyInUse = newUIErrFn(
|
||||||
@ -145,6 +145,12 @@ Example 1:
|
|||||||
"",
|
"",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
uiErrPortAccess = newUIErrFn(
|
||||||
|
"Unable to use specified port",
|
||||||
|
"Please ensure MinIO binary has 'cap_net_bind_service=+ep' permissions",
|
||||||
|
`Use 'sudo setcap cap_net_bind_service=+ep /path/to/minio' to provide sufficient permissions`,
|
||||||
|
)
|
||||||
|
|
||||||
uiErrNoPermissionsToAccessDirFiles = newUIErrFn(
|
uiErrNoPermissionsToAccessDirFiles = newUIErrFn(
|
||||||
"Missing permissions to access the specified path",
|
"Missing permissions to access the specified path",
|
||||||
"Please ensure the specified path can be accessed",
|
"Please ensure the specified path can be accessed",
|
||||||
@ -154,7 +160,7 @@ Example 1:
|
|||||||
uiErrSSLUnexpectedError = newUIErrFn(
|
uiErrSSLUnexpectedError = newUIErrFn(
|
||||||
"Invalid TLS certificate",
|
"Invalid TLS certificate",
|
||||||
"Please check the content of your certificate data",
|
"Please check the content of your certificate data",
|
||||||
`Only PEM (x.509) format is accepted as valid public & private certificates.`,
|
`Only PEM (x.509) format is accepted as valid public & private certificates`,
|
||||||
)
|
)
|
||||||
|
|
||||||
uiErrSSLUnexpectedData = newUIErrFn(
|
uiErrSSLUnexpectedData = newUIErrFn(
|
||||||
@ -171,8 +177,8 @@ Example 1:
|
|||||||
|
|
||||||
uiErrNoCertsAndHTTPSEndpoints = newUIErrFn(
|
uiErrNoCertsAndHTTPSEndpoints = newUIErrFn(
|
||||||
"HTTPS specified in endpoints, but no TLS certificate is found on the local machine",
|
"HTTPS specified in endpoints, but no TLS certificate is found on the local machine",
|
||||||
"Please add a certificate or switch to HTTP.",
|
"Please add TLS certificate or use HTTP endpoints only",
|
||||||
"Refer to https://docs.min.io/docs/how-to-secure-access-to-minio-server-with-tls for information about how to load a TLS certificate in your server.",
|
"Refer to https://docs.min.io/docs/how-to-secure-access-to-minio-server-with-tls for information about how to load a TLS certificate in your server",
|
||||||
)
|
)
|
||||||
|
|
||||||
uiErrCertsAndHTTPEndpoints = newUIErrFn(
|
uiErrCertsAndHTTPEndpoints = newUIErrFn(
|
||||||
|
Loading…
Reference in New Issue
Block a user