| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | /* | 
					
						
							|  |  |  |  * MinIO Cloud Storage, (C) 2019 MinIO, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package cmd | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2019-10-17 19:09:50 +08:00
										 |  |  | 	"net" | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-31 12:06:13 +08:00
										 |  |  | 	"github.com/minio/minio-go/v6/pkg/set" | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 	"github.com/minio/minio/pkg/cpu" | 
					
						
							|  |  |  | 	"github.com/minio/minio/pkg/disk" | 
					
						
							| 
									
										
										
										
											2019-09-13 05:52:30 +08:00
										 |  |  | 	"github.com/minio/minio/pkg/madmin" | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 	"github.com/minio/minio/pkg/mem" | 
					
						
							| 
									
										
										
										
											2019-10-03 22:48:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	cpuhw "github.com/shirou/gopsutil/cpu" | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | // getLocalMemUsage - returns ServerMemUsageInfo for all zones, endpoints.
 | 
					
						
							|  |  |  | func getLocalMemUsage(endpointZones EndpointZones, r *http.Request) ServerMemUsageInfo { | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 	var memUsages []mem.Usage | 
					
						
							|  |  |  | 	var historicUsages []mem.Usage | 
					
						
							|  |  |  | 	seenHosts := set.NewStringSet() | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 	for _, ep := range endpointZones { | 
					
						
							|  |  |  | 		for _, endpoint := range ep.Endpoints { | 
					
						
							|  |  |  | 			if seenHosts.Contains(endpoint.Host) { | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			seenHosts.Add(endpoint.Host) | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 			// Only proceed for local endpoints
 | 
					
						
							|  |  |  | 			if endpoint.IsLocal { | 
					
						
							|  |  |  | 				memUsages = append(memUsages, mem.GetUsage()) | 
					
						
							|  |  |  | 				historicUsages = append(historicUsages, mem.GetHistoricUsage()) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	addr := r.Host | 
					
						
							|  |  |  | 	if globalIsDistXL { | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 		addr = GetLocalPeer(endpointZones) | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return ServerMemUsageInfo{ | 
					
						
							|  |  |  | 		Addr:          addr, | 
					
						
							|  |  |  | 		Usage:         memUsages, | 
					
						
							|  |  |  | 		HistoricUsage: historicUsages, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | // getLocalCPULoad - returns ServerCPULoadInfo for all zones, endpoints.
 | 
					
						
							|  |  |  | func getLocalCPULoad(endpointZones EndpointZones, r *http.Request) ServerCPULoadInfo { | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 	var cpuLoads []cpu.Load | 
					
						
							|  |  |  | 	var historicLoads []cpu.Load | 
					
						
							|  |  |  | 	seenHosts := set.NewStringSet() | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 	for _, ep := range endpointZones { | 
					
						
							|  |  |  | 		for _, endpoint := range ep.Endpoints { | 
					
						
							|  |  |  | 			if seenHosts.Contains(endpoint.Host) { | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			seenHosts.Add(endpoint.Host) | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 			// Only proceed for local endpoints
 | 
					
						
							|  |  |  | 			if endpoint.IsLocal { | 
					
						
							|  |  |  | 				cpuLoads = append(cpuLoads, cpu.GetLoad()) | 
					
						
							|  |  |  | 				historicLoads = append(historicLoads, cpu.GetHistoricLoad()) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	addr := r.Host | 
					
						
							|  |  |  | 	if globalIsDistXL { | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 		addr = GetLocalPeer(endpointZones) | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return ServerCPULoadInfo{ | 
					
						
							|  |  |  | 		Addr:         addr, | 
					
						
							|  |  |  | 		Load:         cpuLoads, | 
					
						
							|  |  |  | 		HistoricLoad: historicLoads, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | // getLocalDrivesPerf - returns ServerDrivesPerfInfo for all zones, endpoints.
 | 
					
						
							|  |  |  | func getLocalDrivesPerf(endpointZones EndpointZones, size int64, r *http.Request) madmin.ServerDrivesPerfInfo { | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 	var dps []disk.Performance | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 	for _, ep := range endpointZones { | 
					
						
							|  |  |  | 		for _, endpoint := range ep.Endpoints { | 
					
						
							|  |  |  | 			// Only proceed for local endpoints
 | 
					
						
							|  |  |  | 			if endpoint.IsLocal { | 
					
						
							|  |  |  | 				if _, err := os.Stat(endpoint.Path); err != nil { | 
					
						
							|  |  |  | 					// Since this drive is not available, add relevant details and proceed
 | 
					
						
							|  |  |  | 					dps = append(dps, disk.Performance{Path: endpoint.Path, Error: err.Error()}) | 
					
						
							|  |  |  | 					continue | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				dp := disk.GetPerformance(pathJoin(endpoint.Path, minioMetaTmpBucket, mustGetUUID()), size) | 
					
						
							|  |  |  | 				dp.Path = endpoint.Path | 
					
						
							|  |  |  | 				dps = append(dps, dp) | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	addr := r.Host | 
					
						
							|  |  |  | 	if globalIsDistXL { | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 		addr = GetLocalPeer(endpointZones) | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-09-13 05:52:30 +08:00
										 |  |  | 	return madmin.ServerDrivesPerfInfo{ | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 		Addr: addr, | 
					
						
							|  |  |  | 		Perf: dps, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-03 22:48:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | // getLocalCPUInfo - returns ServerCPUHardwareInfo for all zones, endpoints.
 | 
					
						
							|  |  |  | func getLocalCPUInfo(endpointZones EndpointZones, r *http.Request) madmin.ServerCPUHardwareInfo { | 
					
						
							| 
									
										
										
										
											2019-10-03 22:48:38 +08:00
										 |  |  | 	var cpuHardwares []cpuhw.InfoStat | 
					
						
							|  |  |  | 	seenHosts := set.NewStringSet() | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 	for _, ep := range endpointZones { | 
					
						
							|  |  |  | 		for _, endpoint := range ep.Endpoints { | 
					
						
							|  |  |  | 			if seenHosts.Contains(endpoint.Host) { | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// Add to the list of visited hosts
 | 
					
						
							|  |  |  | 			seenHosts.Add(endpoint.Host) | 
					
						
							|  |  |  | 			// Only proceed for local endpoints
 | 
					
						
							|  |  |  | 			if endpoint.IsLocal { | 
					
						
							|  |  |  | 				cpuHardware, err := cpuhw.Info() | 
					
						
							|  |  |  | 				if err != nil { | 
					
						
							|  |  |  | 					return madmin.ServerCPUHardwareInfo{ | 
					
						
							|  |  |  | 						Error: err.Error(), | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-10-03 22:48:38 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 				cpuHardwares = append(cpuHardwares, cpuHardware...) | 
					
						
							| 
									
										
										
										
											2019-10-03 22:48:38 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	addr := r.Host | 
					
						
							|  |  |  | 	if globalIsDistXL { | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 		addr = GetLocalPeer(endpointZones) | 
					
						
							| 
									
										
										
										
											2019-10-03 22:48:38 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return madmin.ServerCPUHardwareInfo{ | 
					
						
							|  |  |  | 		Addr:    addr, | 
					
						
							|  |  |  | 		CPUInfo: cpuHardwares, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-17 19:09:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | // getLocalNetworkInfo - returns ServerNetworkHardwareInfo for all zones, endpoints.
 | 
					
						
							|  |  |  | func getLocalNetworkInfo(endpointZones EndpointZones, r *http.Request) madmin.ServerNetworkHardwareInfo { | 
					
						
							| 
									
										
										
										
											2019-10-17 19:09:50 +08:00
										 |  |  | 	var networkHardwares []net.Interface | 
					
						
							|  |  |  | 	seenHosts := set.NewStringSet() | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 	for _, ep := range endpointZones { | 
					
						
							|  |  |  | 		for _, endpoint := range ep.Endpoints { | 
					
						
							|  |  |  | 			if seenHosts.Contains(endpoint.Host) { | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// Add to the list of visited hosts
 | 
					
						
							|  |  |  | 			seenHosts.Add(endpoint.Host) | 
					
						
							|  |  |  | 			// Only proceed for local endpoints
 | 
					
						
							|  |  |  | 			if endpoint.IsLocal { | 
					
						
							|  |  |  | 				networkHardware, err := net.Interfaces() | 
					
						
							|  |  |  | 				if err != nil { | 
					
						
							|  |  |  | 					return madmin.ServerNetworkHardwareInfo{ | 
					
						
							|  |  |  | 						Error: err.Error(), | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-10-17 19:09:50 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 				networkHardwares = append(networkHardwares, networkHardware...) | 
					
						
							| 
									
										
										
										
											2019-10-17 19:09:50 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	addr := r.Host | 
					
						
							|  |  |  | 	if globalIsDistXL { | 
					
						
							| 
									
										
										
										
											2019-11-20 09:42:27 +08:00
										 |  |  | 		addr = GetLocalPeer(endpointZones) | 
					
						
							| 
									
										
										
										
											2019-10-17 19:09:50 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return madmin.ServerNetworkHardwareInfo{ | 
					
						
							|  |  |  | 		Addr:        addr, | 
					
						
							|  |  |  | 		NetworkInfo: networkHardwares, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-12-12 06:27:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // getLocalServerProperty - returns ServerDrivesPerfInfo for only the
 | 
					
						
							|  |  |  | // local endpoints from given list of endpoints
 | 
					
						
							|  |  |  | func getLocalServerProperty(endpointZones EndpointZones, r *http.Request) madmin.ServerProperties { | 
					
						
							|  |  |  | 	var disks []madmin.Disk | 
					
						
							|  |  |  | 	addr := r.Host | 
					
						
							|  |  |  | 	if globalIsDistXL { | 
					
						
							|  |  |  | 		addr = GetLocalPeer(endpointZones) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	network := make(map[string]string) | 
					
						
							|  |  |  | 	for _, ep := range endpointZones { | 
					
						
							|  |  |  | 		for _, endpoint := range ep.Endpoints { | 
					
						
							| 
									
										
										
										
											2020-02-02 09:45:29 +08:00
										 |  |  | 			nodeName := endpoint.Host | 
					
						
							|  |  |  | 			if nodeName == "" { | 
					
						
							|  |  |  | 				nodeName = r.Host | 
					
						
							| 
									
										
										
										
											2019-12-12 06:27:03 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			if endpoint.IsLocal { | 
					
						
							| 
									
										
										
										
											2020-02-02 09:45:29 +08:00
										 |  |  | 				// Only proceed for local endpoints
 | 
					
						
							|  |  |  | 				network[nodeName] = "online" | 
					
						
							|  |  |  | 				var di = madmin.Disk{ | 
					
						
							|  |  |  | 					DrivePath: endpoint.Path, | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				diInfo, err := disk.GetInfo(endpoint.Path) | 
					
						
							|  |  |  | 				if err != nil { | 
					
						
							|  |  |  | 					if os.IsNotExist(err) || isSysErrPathNotFound(err) { | 
					
						
							|  |  |  | 						di.State = madmin.DriveStateMissing | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						di.State = madmin.DriveStateCorrupt | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					di.State = madmin.DriveStateOk | 
					
						
							|  |  |  | 					di.DrivePath = endpoint.Path | 
					
						
							|  |  |  | 					di.TotalSpace = diInfo.Total | 
					
						
							|  |  |  | 					di.UsedSpace = diInfo.Total - diInfo.Free | 
					
						
							|  |  |  | 					di.Utilization = float64((diInfo.Total - diInfo.Free) / diInfo.Total * 100) | 
					
						
							| 
									
										
										
										
											2019-12-12 06:27:03 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				disks = append(disks, di) | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2020-02-02 09:45:29 +08:00
										 |  |  | 				_, present := network[nodeName] | 
					
						
							|  |  |  | 				if !present { | 
					
						
							|  |  |  | 					err := IsServerResolvable(endpoint) | 
					
						
							|  |  |  | 					if err == nil { | 
					
						
							|  |  |  | 						network[nodeName] = "online" | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						network[nodeName] = "offline" | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-12-12 06:27:03 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return madmin.ServerProperties{ | 
					
						
							|  |  |  | 		State:    "ok", | 
					
						
							|  |  |  | 		Endpoint: addr, | 
					
						
							| 
									
										
										
										
											2019-12-12 09:56:02 +08:00
										 |  |  | 		Uptime:   UTCNow().Unix() - globalBootTime.Unix(), | 
					
						
							| 
									
										
										
										
											2019-12-12 06:27:03 +08:00
										 |  |  | 		Version:  Version, | 
					
						
							|  |  |  | 		CommitID: CommitID, | 
					
						
							|  |  |  | 		Network:  network, | 
					
						
							|  |  |  | 		Disks:    disks, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |