| 
									
										
										
										
											2021-04-19 03:41:13 +08:00
										 |  |  | // Copyright (c) 2015-2021 MinIO, Inc.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This file is part of MinIO Object Storage stack
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU Affero General Public License for more details.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU Affero General Public License
 | 
					
						
							|  |  |  | // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  | package cmd | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2018-12-19 00:26:30 +08:00
										 |  |  | 	"net" | 
					
						
							| 
									
										
										
										
											2021-08-06 06:01:19 +08:00
										 |  |  | 	"net/url" | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | 	"runtime" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 	humanize "github.com/dustin/go-humanize" | 
					
						
							| 
									
										
										
										
											2021-05-06 23:52:02 +08:00
										 |  |  | 	"github.com/minio/madmin-go" | 
					
						
							| 
									
										
										
										
											2021-06-02 05:59:40 +08:00
										 |  |  | 	color "github.com/minio/minio/internal/color" | 
					
						
							|  |  |  | 	"github.com/minio/minio/internal/logger" | 
					
						
							| 
									
										
										
										
											2021-06-15 05:54:37 +08:00
										 |  |  | 	xnet "github.com/minio/pkg/net" | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // generates format string depending on the string length and padding.
 | 
					
						
							|  |  |  | func getFormatStr(strLen int, padding int) string { | 
					
						
							|  |  |  | 	formatStr := fmt.Sprintf("%ds", strLen+padding) | 
					
						
							|  |  |  | 	return "%" + formatStr | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-29 04:03:04 +08:00
										 |  |  | func mustGetStorageInfo(objAPI ObjectLayer) StorageInfo { | 
					
						
							| 
									
										
										
										
											2021-01-05 01:42:09 +08:00
										 |  |  | 	storageInfo, _ := objAPI.StorageInfo(GlobalContext) | 
					
						
							| 
									
										
										
										
											2020-05-29 04:03:04 +08:00
										 |  |  | 	return storageInfo | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | // Prints the formatted startup message.
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 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")) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-13 00:22:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-21 14:04:47 +08:00
										 |  |  | 	strippedAPIEndpoints := stripStandardPorts(apiEndpoints, globalMinioHost) | 
					
						
							| 
									
										
										
										
											2018-03-29 05:14:06 +08:00
										 |  |  | 	// If cache layer is enabled, print cache capacity.
 | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	cachedObjAPI := newCachedObjectLayerFn() | 
					
						
							|  |  |  | 	if cachedObjAPI != nil { | 
					
						
							| 
									
										
										
										
											2020-04-10 00:30:02 +08:00
										 |  |  | 		printCacheStorageInfo(cachedObjAPI.StorageInfo(GlobalContext)) | 
					
						
							| 
									
										
										
										
											2018-03-29 05:14:06 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-22 19:28:13 +08:00
										 |  |  | 	// Object layer is initialized then print StorageInfo.
 | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							| 
									
										
										
										
											2017-12-22 19:28:13 +08:00
										 |  |  | 	if objAPI != nil { | 
					
						
							| 
									
										
										
										
											2020-05-29 04:03:04 +08:00
										 |  |  | 		printStorageInfo(mustGetStorageInfo(objAPI)) | 
					
						
							| 
									
										
										
										
											2017-12-22 19:28:13 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-11 08:43:48 +08:00
										 |  |  | 	// Prints credential, region and browser access.
 | 
					
						
							| 
									
										
										
										
											2017-06-01 00:21:28 +08:00
										 |  |  | 	printServerCommonMsg(strippedAPIEndpoints) | 
					
						
							| 
									
										
										
										
											2017-01-11 08:43:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Prints `mc` cli configuration message chooses
 | 
					
						
							|  |  |  | 	// first endpoint as default.
 | 
					
						
							| 
									
										
										
										
											2017-06-10 10:50:51 +08:00
										 |  |  | 	printCLIAccessMsg(strippedAPIEndpoints[0], "myminio") | 
					
						
							| 
									
										
										
										
											2017-01-11 08:43:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Prints documentation message.
 | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | 	printObjectAPIMsg() | 
					
						
							| 
									
										
										
										
											2016-10-14 19:48:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-18 11:27:04 +08:00
										 |  |  | 	if globalMinioConsolePortAuto && globalBrowserEnabled { | 
					
						
							|  |  |  | 		msg := fmt.Sprintf("\nWARNING: Console endpoint is listening on a dynamic port (%s), please use --console-address \":PORT\" to choose a static port.", | 
					
						
							|  |  |  | 			globalMinioConsolePort) | 
					
						
							|  |  |  | 		logStartupMessage(color.RedBold(msg)) | 
					
						
							| 
									
										
										
										
											2016-10-14 19:48:08 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-06 06:01:19 +08:00
										 |  |  | // Returns true if input is IPv6
 | 
					
						
							|  |  |  | func isIPv6(host string) bool { | 
					
						
							| 
									
										
										
										
											2018-12-19 00:26:30 +08:00
										 |  |  | 	h, _, err := net.SplitHostPort(host) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		h = host | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ip := net.ParseIP(h) | 
					
						
							| 
									
										
										
										
											2021-08-06 06:01:19 +08:00
										 |  |  | 	return ip.To16() != nil && ip.To4() == nil | 
					
						
							| 
									
										
										
										
											2018-12-19 00:26:30 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-01 00:21:28 +08:00
										 |  |  | // strip api endpoints list with standard ports such as
 | 
					
						
							|  |  |  | // port "80" and "443" before displaying on the startup
 | 
					
						
							|  |  |  | // banner.  Returns a new list of API endpoints.
 | 
					
						
							| 
									
										
										
										
											2021-06-21 14:04:47 +08:00
										 |  |  | func stripStandardPorts(apiEndpoints []string, host string) (newAPIEndpoints []string) { | 
					
						
							| 
									
										
										
										
											2021-08-06 06:01:19 +08:00
										 |  |  | 	if len(apiEndpoints) == 1 { | 
					
						
							|  |  |  | 		return apiEndpoints | 
					
						
							| 
									
										
										
										
											2021-07-24 06:22:25 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-01 00:21:28 +08:00
										 |  |  | 	newAPIEndpoints = make([]string, len(apiEndpoints)) | 
					
						
							|  |  |  | 	// Check all API endpoints for standard ports and strip them.
 | 
					
						
							|  |  |  | 	for i, apiEndpoint := range apiEndpoints { | 
					
						
							| 
									
										
										
										
											2021-08-06 06:01:19 +08:00
										 |  |  | 		_, err := xnet.ParseHTTPURL(apiEndpoint) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		u, err := url.Parse(apiEndpoint) | 
					
						
							| 
									
										
										
										
											2017-06-01 00:21:28 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-08-06 06:01:19 +08:00
										 |  |  | 		if host == "" && isIPv6(u.Hostname()) { | 
					
						
							|  |  |  | 			// Skip all IPv6 endpoints
 | 
					
						
							| 
									
										
										
										
											2018-12-19 00:26:30 +08:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-08-06 06:01:19 +08:00
										 |  |  | 		if u.Port() == "80" && u.Scheme == "http" || u.Port() == "443" && u.Scheme == "https" { | 
					
						
							|  |  |  | 			u.Host = u.Hostname() | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-12-19 00:26:30 +08:00
										 |  |  | 		newAPIEndpoints[i] = u.String() | 
					
						
							| 
									
										
										
										
											2017-06-01 00:21:28 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return newAPIEndpoints | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | // Prints common server startup message. Prints credential, region and browser access.
 | 
					
						
							| 
									
										
										
										
											2017-01-11 08:43:48 +08:00
										 |  |  | func printServerCommonMsg(apiEndpoints []string) { | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | 	// Get saved credentials.
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	cred := globalActiveCred | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Get saved region.
 | 
					
						
							| 
									
										
										
										
											2021-11-26 05:06:25 +08:00
										 |  |  | 	region := globalSite.Region | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-11 08:43:48 +08:00
										 |  |  | 	apiEndpointStr := strings.Join(apiEndpoints, "  ") | 
					
						
							| 
									
										
										
										
											2017-06-01 00:21:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | 	// Colorize the message and print.
 | 
					
						
							| 
									
										
										
										
											2021-06-18 11:27:04 +08:00
										 |  |  | 	logStartupMessage(color.Blue("API: ") + color.Bold(fmt.Sprintf("%s ", apiEndpointStr))) | 
					
						
							| 
									
										
										
										
											2019-10-05 01:35:33 +08:00
										 |  |  | 	if color.IsTerminal() && !globalCLIContext.Anonymous { | 
					
						
							| 
									
										
										
										
											2021-01-06 02:22:57 +08:00
										 |  |  | 		logStartupMessage(color.Blue("RootUser: ") + color.Bold(fmt.Sprintf("%s ", cred.AccessKey))) | 
					
						
							| 
									
										
										
										
											2021-01-07 02:38:07 +08:00
										 |  |  | 		logStartupMessage(color.Blue("RootPass: ") + color.Bold(fmt.Sprintf("%s ", cred.SecretKey))) | 
					
						
							| 
									
										
										
										
											2018-10-17 04:19:12 +08:00
										 |  |  | 		if region != "" { | 
					
						
							| 
									
										
										
										
											2021-01-07 02:38:07 +08:00
										 |  |  | 			logStartupMessage(color.Blue("Region: ") + color.Bold(fmt.Sprintf(getFormatStr(len(region), 2), region))) | 
					
						
							| 
									
										
										
										
											2018-10-17 04:19:12 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-05-16 09:17:02 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-14 16:11:03 +08:00
										 |  |  | 	printEventNotifiers() | 
					
						
							| 
									
										
										
										
											2021-04-30 10:01:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if globalBrowserEnabled { | 
					
						
							| 
									
										
										
										
											2021-06-21 14:04:47 +08:00
										 |  |  | 		consoleEndpointStr := strings.Join(stripStandardPorts(getConsoleEndpoints(), globalMinioConsoleHost), " ") | 
					
						
							| 
									
										
										
										
											2021-06-18 11:27:04 +08:00
										 |  |  | 		logStartupMessage(color.Blue("\nConsole: ") + color.Bold(fmt.Sprintf("%s ", consoleEndpointStr))) | 
					
						
							|  |  |  | 		if color.IsTerminal() && !globalCLIContext.Anonymous { | 
					
						
							|  |  |  | 			logStartupMessage(color.Blue("RootUser: ") + color.Bold(fmt.Sprintf("%s ", cred.AccessKey))) | 
					
						
							|  |  |  | 			logStartupMessage(color.Blue("RootPass: ") + color.Bold(fmt.Sprintf("%s ", cred.SecretKey))) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-04-30 10:01:43 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-14 02:00:40 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-18 11:27:04 +08:00
										 |  |  | // Prints startup message for Object API acces, prints link to our SDK documentation.
 | 
					
						
							|  |  |  | func printObjectAPIMsg() { | 
					
						
							|  |  |  | 	logStartupMessage(color.Blue("\nDocumentation: ") + "https://docs.min.io") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-14 02:00:40 +08:00
										 |  |  | // Prints bucket notification configurations.
 | 
					
						
							|  |  |  | func printEventNotifiers() { | 
					
						
							| 
									
										
										
										
											2019-11-14 09:38:05 +08:00
										 |  |  | 	if globalNotificationSys == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-22 00:38:32 +08:00
										 |  |  | 	arns := globalNotificationSys.GetARNList(true) | 
					
						
							| 
									
										
										
										
											2018-03-16 04:03:41 +08:00
										 |  |  | 	if len(arns) == 0 { | 
					
						
							| 
									
										
										
										
											2017-05-16 09:17:02 +08:00
										 |  |  | 		return | 
					
						
							| 
									
										
										
										
											2016-09-14 02:00:40 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-03-16 04:03:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-05 01:35:33 +08:00
										 |  |  | 	arnMsg := color.Blue("SQS ARNs: ") | 
					
						
							| 
									
										
										
										
											2018-03-16 04:03:41 +08:00
										 |  |  | 	for _, arn := range arns { | 
					
						
							| 
									
										
										
										
											2021-01-07 02:38:07 +08:00
										 |  |  | 		arnMsg += color.Bold(fmt.Sprintf("%s ", arn)) | 
					
						
							| 
									
										
										
										
											2016-09-10 17:23:28 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-03-16 04:03:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-22 16:24:32 +08:00
										 |  |  | 	logStartupMessage(arnMsg) | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Prints startup message for command line access. Prints link to our documentation
 | 
					
						
							|  |  |  | // and custom platform specific message.
 | 
					
						
							| 
									
										
										
										
											2017-06-10 10:50:51 +08:00
										 |  |  | func printCLIAccessMsg(endPoint string, alias string) { | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | 	// Get saved credentials.
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 	cred := globalActiveCred | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-18 11:27:04 +08:00
										 |  |  | 	const mcQuickStartGuide = "https://docs.min.io/docs/minio-client-quickstart-guide" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | 	// Configure 'mc', following block prints platform specific information for minio client.
 | 
					
						
							| 
									
										
										
										
											2020-01-07 00:42:47 +08:00
										 |  |  | 	if color.IsTerminal() && !globalCLIContext.Anonymous { | 
					
						
							| 
									
										
										
										
											2021-06-18 11:27:04 +08:00
										 |  |  | 		logStartupMessage(color.Blue("\nCommand-line: ") + mcQuickStartGuide) | 
					
						
							| 
									
										
										
										
											2018-10-17 04:19:12 +08:00
										 |  |  | 		if runtime.GOOS == globalWindowsOSName { | 
					
						
							| 
									
										
										
										
											2020-08-18 08:39:55 +08:00
										 |  |  | 			mcMessage := fmt.Sprintf("$ mc.exe alias set %s %s %s %s", alias, | 
					
						
							| 
									
										
										
										
											2019-10-05 01:35:33 +08:00
										 |  |  | 				endPoint, cred.AccessKey, cred.SecretKey) | 
					
						
							| 
									
										
										
										
											2019-09-22 16:24:32 +08:00
										 |  |  | 			logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage)) | 
					
						
							| 
									
										
										
										
											2018-10-17 04:19:12 +08:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2020-08-18 08:39:55 +08:00
										 |  |  | 			mcMessage := fmt.Sprintf("$ mc alias set %s %s %s %s", alias, | 
					
						
							| 
									
										
										
										
											2019-10-05 01:35:33 +08:00
										 |  |  | 				endPoint, cred.AccessKey, cred.SecretKey) | 
					
						
							| 
									
										
										
										
											2019-09-22 16:24:32 +08:00
										 |  |  | 			logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage)) | 
					
						
							| 
									
										
										
										
											2018-10-17 04:19:12 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-07-13 14:21:18 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | // Get formatted disk/storage info message.
 | 
					
						
							| 
									
										
										
										
											2016-10-10 14:03:10 +08:00
										 |  |  | func getStorageInfoMsg(storageInfo StorageInfo) string { | 
					
						
							| 
									
										
										
										
											2018-05-24 08:30:25 +08:00
										 |  |  | 	var msg string | 
					
						
							| 
									
										
										
										
											2020-03-18 06:25:00 +08:00
										 |  |  | 	var mcMessage string | 
					
						
							| 
									
										
										
										
											2020-12-22 01:35:19 +08:00
										 |  |  | 	onlineDisks, offlineDisks := getOnlineOfflineDisksStats(storageInfo.Disks) | 
					
						
							| 
									
										
										
										
											2021-03-05 06:36:23 +08:00
										 |  |  | 	if storageInfo.Backend.Type == madmin.Erasure { | 
					
						
							| 
									
										
										
										
											2020-12-22 01:35:19 +08:00
										 |  |  | 		if offlineDisks.Sum() > 0 { | 
					
						
							| 
									
										
										
										
											2020-04-13 09:08:27 +08:00
										 |  |  | 			mcMessage = "Use `mc admin info` to look for latest server/disk info\n" | 
					
						
							| 
									
										
										
										
											2020-03-18 06:25:00 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-03-22 01:02:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 01:35:19 +08:00
										 |  |  | 		diskInfo := fmt.Sprintf(" %d Online, %d Offline. ", onlineDisks.Sum(), offlineDisks.Sum()) | 
					
						
							| 
									
										
										
										
											2019-10-05 01:35:33 +08:00
										 |  |  | 		msg += color.Blue("Status:") + fmt.Sprintf(getFormatStr(len(diskInfo), 8), diskInfo) | 
					
						
							| 
									
										
										
										
											2020-03-22 01:02:20 +08:00
										 |  |  | 		if len(mcMessage) > 0 { | 
					
						
							|  |  |  | 			msg = fmt.Sprintf("%s %s", mcMessage, msg) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return msg | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Prints startup message of storage capacity and erasure information.
 | 
					
						
							| 
									
										
										
										
											2016-10-10 14:03:10 +08:00
										 |  |  | func printStorageInfo(storageInfo StorageInfo) { | 
					
						
							| 
									
										
										
										
											2018-05-24 08:30:25 +08:00
										 |  |  | 	if msg := getStorageInfoMsg(storageInfo); msg != "" { | 
					
						
							| 
									
										
										
										
											2020-03-18 06:25:00 +08:00
										 |  |  | 		if globalCLIContext.Quiet { | 
					
						
							|  |  |  | 			logger.Info(msg) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-09-22 16:24:32 +08:00
										 |  |  | 		logStartupMessage(msg) | 
					
						
							| 
									
										
										
										
											2018-05-24 08:30:25 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-10-06 03:48:07 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-14 19:48:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 02:30:14 +08:00
										 |  |  | func printCacheStorageInfo(storageInfo CacheStorageInfo) { | 
					
						
							| 
									
										
										
										
											2019-10-05 01:35:33 +08:00
										 |  |  | 	msg := fmt.Sprintf("%s %s Free, %s Total", color.Blue("Cache Capacity:"), | 
					
						
							| 
									
										
										
										
											2020-08-25 03:11:20 +08:00
										 |  |  | 		humanize.IBytes(storageInfo.Free), | 
					
						
							|  |  |  | 		humanize.IBytes(storageInfo.Total)) | 
					
						
							| 
									
										
										
										
											2019-09-22 16:24:32 +08:00
										 |  |  | 	logStartupMessage(msg) | 
					
						
							| 
									
										
										
										
											2018-03-29 05:14:06 +08:00
										 |  |  | } |