| 
									
										
										
										
											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/>.
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | package cmd | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 	"encoding/gob" | 
					
						
							| 
									
										
										
										
											2020-06-18 05:49:26 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	"io" | 
					
						
							|  |  |  | 	"net/url" | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2020-10-10 11:36:00 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-20 08:53:08 +08:00
										 |  |  | 	"github.com/minio/madmin-go/v3" | 
					
						
							| 
									
										
										
										
											2023-01-19 21:22:16 +08:00
										 |  |  | 	"github.com/minio/minio/internal/bucket/bandwidth" | 
					
						
							| 
									
										
										
										
											2021-06-02 05:59:40 +08:00
										 |  |  | 	"github.com/minio/minio/internal/event" | 
					
						
							|  |  |  | 	xhttp "github.com/minio/minio/internal/http" | 
					
						
							|  |  |  | 	"github.com/minio/minio/internal/logger" | 
					
						
							|  |  |  | 	"github.com/minio/minio/internal/rest" | 
					
						
							| 
									
										
										
										
											2023-09-05 03:57:37 +08:00
										 |  |  | 	"github.com/minio/pkg/v2/logger/message/log" | 
					
						
							|  |  |  | 	xnet "github.com/minio/pkg/v2/net" | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 	"github.com/tinylib/msgp/msgp" | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | // client to talk to peer Nodes.
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | type peerRESTClient struct { | 
					
						
							|  |  |  | 	host       *xnet.Host | 
					
						
							|  |  |  | 	restClient *rest.Client | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Wrapper to restClient.Call to handle network errors, in case of network error the connection is marked disconnected
 | 
					
						
							|  |  |  | // permanently. The only way to restore the connection is at the xl-sets layer by xlsets.monitorAndConnectEndpoints()
 | 
					
						
							|  |  |  | // after verifying format.json
 | 
					
						
							|  |  |  | func (client *peerRESTClient) call(method string, values url.Values, body io.Reader, length int64) (respBody io.ReadCloser, err error) { | 
					
						
							| 
									
										
										
										
											2020-04-10 00:30:02 +08:00
										 |  |  | 	return client.callWithContext(GlobalContext, method, values, body, length) | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Wrapper to restClient.Call to handle network errors, in case of network error the connection is marked disconnected
 | 
					
						
							|  |  |  | // permanently. The only way to restore the connection is at the xl-sets layer by xlsets.monitorAndConnectEndpoints()
 | 
					
						
							|  |  |  | // after verifying format.json
 | 
					
						
							|  |  |  | func (client *peerRESTClient) callWithContext(ctx context.Context, method string, values url.Values, body io.Reader, length int64) (respBody io.ReadCloser, err error) { | 
					
						
							| 
									
										
										
										
											2023-03-08 00:13:28 +08:00
										 |  |  | 	if client == nil || !client.IsOnline() { | 
					
						
							|  |  |  | 		return nil, errPeerNotReachable | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	if values == nil { | 
					
						
							|  |  |  | 		values = make(url.Values) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-05 00:45:06 +08:00
										 |  |  | 	respBody, err = client.restClient.Call(ctx, method, values, body, length) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		return respBody, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Stringer provides a canonicalized representation of node.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) String() string { | 
					
						
							|  |  |  | 	return client.host.String() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-23 01:16:07 +08:00
										 |  |  | // IsOnline returns true if the peer client is online.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) IsOnline() bool { | 
					
						
							|  |  |  | 	return client.restClient.IsOnline() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | // Close - marks the client as closed.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) Close() error { | 
					
						
							|  |  |  | 	client.restClient.Close() | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // GetLocks - fetch older locks for a remote node.
 | 
					
						
							| 
									
										
										
										
											2020-12-10 23:28:37 +08:00
										 |  |  | func (client *peerRESTClient) GetLocks() (lockMap map[string][]lockRequesterInfo, err error) { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	respBody, err := client.call(peerRESTMethodGetLocks, nil, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-12-10 23:28:37 +08:00
										 |  |  | 	lockMap = map[string][]lockRequesterInfo{} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2020-12-10 23:28:37 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&lockMap) | 
					
						
							|  |  |  | 	return lockMap, err | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-02 06:31:35 +08:00
										 |  |  | // LocalStorageInfo - fetch server information for a remote node.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) LocalStorageInfo() (info StorageInfo, err error) { | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodLocalStorageInfo, nil, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2022-12-02 06:31:35 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&info) | 
					
						
							|  |  |  | 	return info, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | // ServerInfo - fetch server information for a remote node.
 | 
					
						
							| 
									
										
										
										
											2019-12-12 06:27:03 +08:00
										 |  |  | func (client *peerRESTClient) ServerInfo() (info madmin.ServerProperties, err error) { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	respBody, err := client.call(peerRESTMethodServerInfo, nil, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&info) | 
					
						
							|  |  |  | 	return info, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | // GetCPUs - fetch CPU information for a remote node.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) GetCPUs(ctx context.Context) (info madmin.CPUs, err error) { | 
					
						
							| 
									
										
										
										
											2020-11-21 04:52:53 +08:00
										 |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodCPUInfo, nil, nil, -1) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&info) | 
					
						
							|  |  |  | 	return info, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | // GetPartitions - fetch disk partition information for a remote node.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) GetPartitions(ctx context.Context) (info madmin.Partitions, err error) { | 
					
						
							| 
									
										
										
										
											2020-11-21 04:52:53 +08:00
										 |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodDiskHwInfo, nil, nil, -1) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&info) | 
					
						
							|  |  |  | 	return info, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | // GetOSInfo - fetch OS information for a remote node.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) GetOSInfo(ctx context.Context) (info madmin.OSInfo, err error) { | 
					
						
							| 
									
										
										
										
											2020-11-21 04:52:53 +08:00
										 |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodOsInfo, nil, nil, -1) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&info) | 
					
						
							|  |  |  | 	return info, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-13 09:58:40 +08:00
										 |  |  | // GetSELinuxInfo - fetch SELinux information for a remote node.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) GetSELinuxInfo(ctx context.Context) (info madmin.SysServices, err error) { | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodSysServices, nil, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2021-08-13 09:58:40 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&info) | 
					
						
							|  |  |  | 	return info, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 08:09:37 +08:00
										 |  |  | // GetSysConfig - fetch sys config for a remote node.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) GetSysConfig(ctx context.Context) (info madmin.SysConfig, err error) { | 
					
						
							| 
									
										
										
										
											2022-01-06 17:51:10 +08:00
										 |  |  | 	sent := time.Now() | 
					
						
							| 
									
										
										
										
											2021-08-25 08:09:37 +08:00
										 |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodSysConfig, nil, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-01-06 17:51:10 +08:00
										 |  |  | 	roundtrip := int32(time.Since(sent).Milliseconds()) | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2022-01-06 17:51:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 08:09:37 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&info) | 
					
						
							| 
									
										
										
										
											2023-05-11 06:20:48 +08:00
										 |  |  | 	if ti, ok := info.Config["time-info"].(madmin.TimeInfo); ok { | 
					
						
							| 
									
										
										
										
											2022-01-06 17:51:10 +08:00
										 |  |  | 		ti.RoundtripDuration = roundtrip | 
					
						
							|  |  |  | 		info.Config["time-info"] = ti | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-25 08:09:37 +08:00
										 |  |  | 	return info, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // GetSysErrors - fetch sys errors for a remote node.
 | 
					
						
							| 
									
										
										
										
											2021-07-30 14:05:34 +08:00
										 |  |  | func (client *peerRESTClient) GetSysErrors(ctx context.Context) (info madmin.SysErrors, err error) { | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodSysErrors, nil, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2021-07-30 14:05:34 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&info) | 
					
						
							|  |  |  | 	return info, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | // GetMemInfo - fetch memory information for a remote node.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) GetMemInfo(ctx context.Context) (info madmin.MemInfo, err error) { | 
					
						
							| 
									
										
										
										
											2020-11-21 04:52:53 +08:00
										 |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodMemInfo, nil, nil, -1) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&info) | 
					
						
							|  |  |  | 	return info, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | // GetMetrics - fetch metrics from a remote node.
 | 
					
						
							| 
									
										
										
										
											2022-10-03 17:10:15 +08:00
										 |  |  | func (client *peerRESTClient) GetMetrics(ctx context.Context, t madmin.MetricType, opts collectMetricsOpts) (info madmin.RealtimeMetrics, err error) { | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	values := make(url.Values) | 
					
						
							| 
									
										
										
										
											2022-10-03 17:10:15 +08:00
										 |  |  | 	values.Set(peerRESTMetricsTypes, strconv.FormatUint(uint64(t), 10)) | 
					
						
							|  |  |  | 	for disk := range opts.disks { | 
					
						
							| 
									
										
										
										
											2023-07-28 02:44:13 +08:00
										 |  |  | 		values.Add(peerRESTDisk, disk) | 
					
						
							| 
									
										
										
										
											2022-08-16 22:13:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-07-19 14:50:30 +08:00
										 |  |  | 	for host := range opts.hosts { | 
					
						
							|  |  |  | 		values.Add(peerRESTHost, host) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-10-03 17:10:15 +08:00
										 |  |  | 	values.Set(peerRESTJobID, opts.jobID) | 
					
						
							| 
									
										
										
										
											2022-11-14 23:16:40 +08:00
										 |  |  | 	values.Set(peerRESTDepID, opts.depID) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodMetrics, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&info) | 
					
						
							|  |  |  | 	return info, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | // GetProcInfo - fetch MinIO process information for a remote node.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) GetProcInfo(ctx context.Context) (info madmin.ProcInfo, err error) { | 
					
						
							| 
									
										
										
										
											2020-11-21 04:52:53 +08:00
										 |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodProcInfo, nil, nil, -1) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&info) | 
					
						
							|  |  |  | 	return info, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | // StartProfiling - Issues profiling command on the peer node.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) StartProfiling(profiler string) error { | 
					
						
							|  |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTProfiler, profiler) | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodStartProfiling, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // DownloadProfileData - download profiled data from a remote node.
 | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | func (client *peerRESTClient) DownloadProfileData() (data map[string][]byte, err error) { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	respBody, err := client.call(peerRESTMethodDownloadProfilingData, nil, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&data) | 
					
						
							|  |  |  | 	return data, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-05 06:34:33 +08:00
										 |  |  | // GetBucketStats - load bucket statistics
 | 
					
						
							|  |  |  | func (client *peerRESTClient) GetBucketStats(bucket string) (BucketStats, error) { | 
					
						
							|  |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTBucket, bucket) | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodGetBucketStats, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return BucketStats{}, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var bs BucketStats | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2021-04-05 06:34:33 +08:00
										 |  |  | 	return bs, msgp.Decode(respBody, &bs) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 16:00:59 +08:00
										 |  |  | // GetSRMetrics- loads site replication metrics, optionally for a specific bucket
 | 
					
						
							|  |  |  | func (client *peerRESTClient) GetSRMetrics() (SRMetricsSummary, error) { | 
					
						
							|  |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodGetSRMetrics, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return SRMetricsSummary{}, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var sm SRMetricsSummary | 
					
						
							|  |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							|  |  |  | 	return sm, msgp.Decode(respBody, &sm) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-24 00:15:30 +08:00
										 |  |  | // GetAllBucketStats - load replication stats for all buckets
 | 
					
						
							|  |  |  | func (client *peerRESTClient) GetAllBucketStats() (BucketStatsMap, error) { | 
					
						
							|  |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodGetAllBucketStats, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-13 03:40:02 +08:00
										 |  |  | 		return BucketStatsMap{}, err | 
					
						
							| 
									
										
										
										
											2022-05-24 00:15:30 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bsMap := BucketStatsMap{} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2022-05-24 00:15:30 +08:00
										 |  |  | 	return bsMap, msgp.Decode(respBody, &bsMap) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-20 04:53:54 +08:00
										 |  |  | // LoadBucketMetadata - load bucket metadata
 | 
					
						
							|  |  |  | func (client *peerRESTClient) LoadBucketMetadata(bucket string) error { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTBucket, bucket) | 
					
						
							| 
									
										
										
										
											2020-05-20 04:53:54 +08:00
										 |  |  | 	respBody, err := client.call(peerRESTMethodLoadBucketMetadata, values, nil, -1) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-20 04:53:54 +08:00
										 |  |  | // DeleteBucketMetadata - Delete bucket metadata
 | 
					
						
							|  |  |  | func (client *peerRESTClient) DeleteBucketMetadata(bucket string) error { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	values := make(url.Values) | 
					
						
							| 
									
										
										
										
											2020-05-20 04:53:54 +08:00
										 |  |  | 	values.Set(peerRESTBucket, bucket) | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodDeleteBucketMetadata, values, nil, -1) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | // DeletePolicy - delete a specific canned policy.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) DeletePolicy(policyName string) (err error) { | 
					
						
							|  |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTPolicy, policyName) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodDeletePolicy, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LoadPolicy - reload a specific canned policy.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) LoadPolicy(policyName string) (err error) { | 
					
						
							|  |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTPolicy, policyName) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodLoadPolicy, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 04:41:06 +08:00
										 |  |  | // LoadPolicyMapping - reload a specific policy mapping
 | 
					
						
							| 
									
										
										
										
											2022-08-24 02:11:45 +08:00
										 |  |  | func (client *peerRESTClient) LoadPolicyMapping(userOrGroup string, userType IAMUserType, isGroup bool) error { | 
					
						
							| 
									
										
										
										
											2019-08-14 04:41:06 +08:00
										 |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTUserOrGroup, userOrGroup) | 
					
						
							| 
									
										
										
										
											2022-08-24 02:11:45 +08:00
										 |  |  | 	values.Set(peerRESTUserType, strconv.Itoa(int(userType))) | 
					
						
							| 
									
										
										
										
											2019-08-14 04:41:06 +08:00
										 |  |  | 	if isGroup { | 
					
						
							|  |  |  | 		values.Set(peerRESTIsGroup, "") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodLoadPolicyMapping, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-08-14 04:41:06 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | // DeleteUser - delete a specific user.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) DeleteUser(accessKey string) (err error) { | 
					
						
							|  |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTUser, accessKey) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodDeleteUser, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 03:10:09 +08:00
										 |  |  | // DeleteServiceAccount - delete a specific service account.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) DeleteServiceAccount(accessKey string) (err error) { | 
					
						
							|  |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTUser, accessKey) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodDeleteServiceAccount, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2020-04-25 03:10:09 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | // LoadUser - reload a specific user.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) LoadUser(accessKey string, temp bool) (err error) { | 
					
						
							|  |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTUser, accessKey) | 
					
						
							|  |  |  | 	values.Set(peerRESTUserTemp, strconv.FormatBool(temp)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodLoadUser, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 03:10:09 +08:00
										 |  |  | // LoadServiceAccount - reload a specific service account.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) LoadServiceAccount(accessKey string) (err error) { | 
					
						
							|  |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTUser, accessKey) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodLoadServiceAccount, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2020-04-25 03:10:09 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 05:25:00 +08:00
										 |  |  | // LoadGroup - send load group command to peers.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) LoadGroup(group string) error { | 
					
						
							|  |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTGroup, group) | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodLoadGroup, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-08-03 05:25:00 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 08:49:47 +08:00
										 |  |  | type binaryInfo struct { | 
					
						
							| 
									
										
										
										
											2021-04-09 00:51:11 +08:00
										 |  |  | 	URL         *url.URL | 
					
						
							|  |  |  | 	Sha256Sum   []byte | 
					
						
							|  |  |  | 	ReleaseInfo string | 
					
						
							| 
									
										
										
										
											2022-07-29 23:34:30 +08:00
										 |  |  | 	BinaryFile  []byte | 
					
						
							| 
									
										
										
										
											2020-07-23 23:03:31 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 23:34:30 +08:00
										 |  |  | // VerifyBinary - sends verify binary message to remote peers.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) VerifyBinary(ctx context.Context, u *url.URL, sha256Sum []byte, releaseInfo string, readerInput []byte) error { | 
					
						
							| 
									
										
										
										
											2019-08-29 06:04:43 +08:00
										 |  |  | 	values := make(url.Values) | 
					
						
							| 
									
										
										
										
											2020-07-23 23:03:31 +08:00
										 |  |  | 	var reader bytes.Buffer | 
					
						
							| 
									
										
										
										
											2022-07-26 08:49:47 +08:00
										 |  |  | 	if err := gob.NewEncoder(&reader).Encode(binaryInfo{ | 
					
						
							| 
									
										
										
										
											2021-04-09 00:51:11 +08:00
										 |  |  | 		URL:         u, | 
					
						
							|  |  |  | 		Sha256Sum:   sha256Sum, | 
					
						
							|  |  |  | 		ReleaseInfo: releaseInfo, | 
					
						
							| 
									
										
										
										
											2022-07-29 23:34:30 +08:00
										 |  |  | 		BinaryFile:  readerInput, | 
					
						
							| 
									
										
										
										
											2020-07-23 23:03:31 +08:00
										 |  |  | 	}); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2019-08-29 06:04:43 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-07-26 08:49:47 +08:00
										 |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodDownloadBinary, values, &reader, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2022-07-26 08:49:47 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // CommitBinary - sends commit binary message to remote peers.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) CommitBinary(ctx context.Context) error { | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodCommitBinary, nil, nil, -1) | 
					
						
							| 
									
										
										
										
											2019-08-29 06:04:43 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-08-29 06:04:43 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | // SignalService - sends signal to peer nodes.
 | 
					
						
							| 
									
										
										
										
											2022-05-17 07:10:51 +08:00
										 |  |  | func (client *peerRESTClient) SignalService(sig serviceSignal, subSys string) error { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	values := make(url.Values) | 
					
						
							| 
									
										
										
										
											2019-08-28 02:37:47 +08:00
										 |  |  | 	values.Set(peerRESTSignal, strconv.Itoa(int(sig))) | 
					
						
							| 
									
										
										
										
											2022-05-17 07:10:51 +08:00
										 |  |  | 	values.Set(peerRESTSubSys, subSys) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	respBody, err := client.call(peerRESTMethodSignalService, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-26 07:42:24 +08:00
										 |  |  | func (client *peerRESTClient) BackgroundHealStatus() (madmin.BgHealState, error) { | 
					
						
							|  |  |  | 	respBody, err := client.call(peerRESTMethodBackgroundHealStatus, nil, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return madmin.BgHealState{}, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-06-26 07:42:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	state := madmin.BgHealState{} | 
					
						
							|  |  |  | 	err = gob.NewDecoder(respBody).Decode(&state) | 
					
						
							|  |  |  | 	return state, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-24 08:38:39 +08:00
										 |  |  | // GetLocalDiskIDs - get a peer's local disks' IDs.
 | 
					
						
							| 
									
										
										
										
											2020-06-10 10:19:03 +08:00
										 |  |  | func (client *peerRESTClient) GetLocalDiskIDs(ctx context.Context) (diskIDs []string) { | 
					
						
							| 
									
										
										
										
											2020-05-24 08:38:39 +08:00
										 |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodGetLocalDiskIDs, nil, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2020-05-24 08:38:39 +08:00
										 |  |  | 	if err = gob.NewDecoder(respBody).Decode(&diskIDs); err != nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return diskIDs | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | // GetMetacacheListing - get a new or existing metacache.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) GetMetacacheListing(ctx context.Context, o listPathOptions) (*metacache, error) { | 
					
						
							| 
									
										
										
										
											2021-12-16 01:19:11 +08:00
										 |  |  | 	if client == nil { | 
					
						
							|  |  |  | 		resp := localMetacacheMgr.getBucket(ctx, o.Bucket).findCache(o) | 
					
						
							|  |  |  | 		return &resp, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 	var reader bytes.Buffer | 
					
						
							|  |  |  | 	err := gob.NewEncoder(&reader).Encode(o) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodGetMetacacheListing, nil, &reader, int64(reader.Len())) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var resp metacache | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 	return &resp, msgp.Decode(respBody, &resp) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // UpdateMetacacheListing - update an existing metacache it will unconditionally be updated to the new state.
 | 
					
						
							|  |  |  | func (client *peerRESTClient) UpdateMetacacheListing(ctx context.Context, m metacache) (metacache, error) { | 
					
						
							| 
									
										
										
										
											2021-12-16 01:19:11 +08:00
										 |  |  | 	if client == nil { | 
					
						
							|  |  |  | 		return localMetacacheMgr.updateCacheEntry(m) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 	b, err := m.MarshalMsg(nil) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return m, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodUpdateMetacacheListing, nil, bytes.NewBuffer(b), int64(len(b))) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return m, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 	var resp metacache | 
					
						
							|  |  |  | 	return resp, msgp.Decode(respBody, &resp) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-11 01:07:49 +08:00
										 |  |  | func (client *peerRESTClient) ReloadPoolMeta(ctx context.Context) error { | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodReloadPoolMeta, nil, nil, 0) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2022-01-11 01:07:49 +08:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2022-10-26 03:36:57 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (client *peerRESTClient) StopRebalance(ctx context.Context) error { | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodStopRebalance, nil, nil, 0) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2022-10-26 03:36:57 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (client *peerRESTClient) LoadRebalanceMeta(ctx context.Context, startRebalance bool) error { | 
					
						
							|  |  |  | 	values := url.Values{} | 
					
						
							|  |  |  | 	values.Set(peerRESTStartRebalance, strconv.FormatBool(startRebalance)) | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodLoadRebalanceMeta, values, nil, 0) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2022-10-26 03:36:57 +08:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2022-01-11 01:07:49 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-20 01:30:42 +08:00
										 |  |  | func (client *peerRESTClient) LoadTransitionTierConfig(ctx context.Context) error { | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodLoadTransitionTierConfig, nil, nil, 0) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2021-04-20 01:30:42 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | func (client *peerRESTClient) doTrace(traceCh chan<- madmin.TraceInfo, doneCh <-chan struct{}, traceOpts madmin.ServiceTraceOpts) { | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 	values := make(url.Values) | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	traceOpts.AddParams(values) | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// To cancel the REST request in case doneCh gets closed.
 | 
					
						
							| 
									
										
										
										
											2020-04-10 00:30:02 +08:00
										 |  |  | 	ctx, cancel := context.WithCancel(GlobalContext) | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	cancelCh := make(chan struct{}) | 
					
						
							|  |  |  | 	defer close(cancelCh) | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 	go func() { | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 		select { | 
					
						
							|  |  |  | 		case <-doneCh: | 
					
						
							|  |  |  | 		case <-cancelCh: | 
					
						
							|  |  |  | 			// There was an error in the REST request.
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		cancel() | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodTrace, values, nil, -1) | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dec := gob.NewDecoder(respBody) | 
					
						
							|  |  |  | 	for { | 
					
						
							| 
									
										
										
										
											2021-05-06 23:52:02 +08:00
										 |  |  | 		var info madmin.TraceInfo | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 		if err = dec.Decode(&info); err != nil { | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-08-01 02:08:39 +08:00
										 |  |  | 		if len(info.NodeName) > 0 { | 
					
						
							|  |  |  | 			select { | 
					
						
							|  |  |  | 			case traceCh <- info: | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				// Do not block on slow receivers.
 | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | func (client *peerRESTClient) doListen(listenCh chan<- event.Event, doneCh <-chan struct{}, v url.Values) { | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | 	// To cancel the REST request in case doneCh gets closed.
 | 
					
						
							| 
									
										
										
										
											2020-04-10 00:30:02 +08:00
										 |  |  | 	ctx, cancel := context.WithCancel(GlobalContext) | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	cancelCh := make(chan struct{}) | 
					
						
							|  |  |  | 	defer close(cancelCh) | 
					
						
							|  |  |  | 	go func() { | 
					
						
							|  |  |  | 		select { | 
					
						
							|  |  |  | 		case <-doneCh: | 
					
						
							|  |  |  | 		case <-cancelCh: | 
					
						
							|  |  |  | 			// There was an error in the REST request.
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		cancel() | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-17 12:30:57 +08:00
										 |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodListen, v, nil, -1) | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dec := gob.NewDecoder(respBody) | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		var ev event.Event | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 		if err := dec.Decode(&ev); err != nil { | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if len(ev.EventVersion) > 0 { | 
					
						
							|  |  |  | 			select { | 
					
						
							|  |  |  | 			case listenCh <- ev: | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				// Do not block on slow receivers.
 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Listen - listen on peers.
 | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | func (client *peerRESTClient) Listen(listenCh chan<- event.Event, doneCh <-chan struct{}, v url.Values) { | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | 	go func() { | 
					
						
							|  |  |  | 		for { | 
					
						
							| 
									
										
										
										
											2019-12-17 12:30:57 +08:00
										 |  |  | 			client.doListen(listenCh, doneCh, v) | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | 			select { | 
					
						
							|  |  |  | 			case <-doneCh: | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				// There was error in the REST request, retry after sometime as probably the peer is down.
 | 
					
						
							|  |  |  | 				time.Sleep(5 * time.Second) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | // Trace - send http trace request to peer nodes
 | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | func (client *peerRESTClient) Trace(traceCh chan<- madmin.TraceInfo, doneCh <-chan struct{}, traceOpts madmin.ServiceTraceOpts) { | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 	go func() { | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 		for { | 
					
						
							| 
									
										
										
										
											2021-03-27 14:24:07 +08:00
										 |  |  | 			client.doTrace(traceCh, doneCh, traceOpts) | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 			select { | 
					
						
							|  |  |  | 			case <-doneCh: | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			default: | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 				// There was error in the REST request, retry after sometime as probably the peer is down.
 | 
					
						
							|  |  |  | 				time.Sleep(5 * time.Second) | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | func (client *peerRESTClient) doConsoleLog(logCh chan log.Info, doneCh <-chan struct{}) { | 
					
						
							| 
									
										
										
										
											2022-05-07 03:39:58 +08:00
										 |  |  | 	// To cancel the REST request in case doneCh gets closed.
 | 
					
						
							|  |  |  | 	ctx, cancel := context.WithCancel(GlobalContext) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cancelCh := make(chan struct{}) | 
					
						
							|  |  |  | 	defer close(cancelCh) | 
					
						
							|  |  |  | 	go func() { | 
					
						
							|  |  |  | 		select { | 
					
						
							|  |  |  | 		case <-doneCh: | 
					
						
							|  |  |  | 		case <-cancelCh: | 
					
						
							|  |  |  | 			// There was an error in the REST request.
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		cancel() | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodLog, nil, nil, -1) | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2022-05-07 03:39:58 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dec := gob.NewDecoder(respBody) | 
					
						
							|  |  |  | 	for { | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | 		var lg log.Info | 
					
						
							| 
									
										
										
										
											2022-05-07 03:39:58 +08:00
										 |  |  | 		if err = dec.Decode(&lg); err != nil { | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | 		select { | 
					
						
							|  |  |  | 		case logCh <- lg: | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			// Do not block on slow receivers.
 | 
					
						
							| 
									
										
										
										
											2022-05-07 03:39:58 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 02:10:48 +08:00
										 |  |  | // ConsoleLog - sends request to peer nodes to get console logs
 | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | func (client *peerRESTClient) ConsoleLog(logCh chan log.Info, doneCh <-chan struct{}) { | 
					
						
							| 
									
										
										
										
											2019-09-04 02:10:48 +08:00
										 |  |  | 	go func() { | 
					
						
							|  |  |  | 		for { | 
					
						
							| 
									
										
										
										
											2022-05-07 03:39:58 +08:00
										 |  |  | 			client.doConsoleLog(logCh, doneCh) | 
					
						
							| 
									
										
										
										
											2019-09-04 02:10:48 +08:00
										 |  |  | 			select { | 
					
						
							|  |  |  | 			case <-doneCh: | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			default: | 
					
						
							| 
									
										
										
										
											2022-05-07 03:39:58 +08:00
										 |  |  | 				// There was error in the REST request, retry after sometime as probably the peer is down.
 | 
					
						
							|  |  |  | 				time.Sleep(5 * time.Second) | 
					
						
							| 
									
										
										
										
											2019-09-04 02:10:48 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | // newPeerRestClients creates new peer clients.
 | 
					
						
							|  |  |  | // The two slices will point to the same clients,
 | 
					
						
							|  |  |  | // but 'all' will contain nil entry for local client.
 | 
					
						
							|  |  |  | // The 'all' slice will be in the same order across the cluster.
 | 
					
						
							| 
									
										
										
										
											2020-12-02 05:50:33 +08:00
										 |  |  | func newPeerRestClients(endpoints EndpointServerPools) (remote, all []*peerRESTClient) { | 
					
						
							| 
									
										
										
										
											2020-10-30 00:25:43 +08:00
										 |  |  | 	if !globalIsDistErasure { | 
					
						
							|  |  |  | 		// Only useful in distributed setups
 | 
					
						
							|  |  |  | 		return nil, nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 	hosts := endpoints.hostsSorted() | 
					
						
							|  |  |  | 	remote = make([]*peerRESTClient, 0, len(hosts)) | 
					
						
							|  |  |  | 	all = make([]*peerRESTClient, len(hosts)) | 
					
						
							|  |  |  | 	for i, host := range hosts { | 
					
						
							|  |  |  | 		if host == nil { | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 		all[i] = newPeerRESTClient(host) | 
					
						
							|  |  |  | 		remote = append(remote, all[i]) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 	if len(all) != len(remote)+1 { | 
					
						
							|  |  |  | 		logger.LogIf(context.Background(), fmt.Errorf("WARNING: Expected number of all hosts (%v) to be remote +1 (%v)", len(all), len(remote))) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 	return remote, all | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Returns a peer rest client.
 | 
					
						
							| 
									
										
										
										
											2020-07-12 13:19:38 +08:00
										 |  |  | func newPeerRESTClient(peer *xnet.Host) *peerRESTClient { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	scheme := "http" | 
					
						
							| 
									
										
										
										
											2020-12-22 13:42:38 +08:00
										 |  |  | 	if globalIsTLS { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 		scheme = "https" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	serverURL := &url.URL{ | 
					
						
							|  |  |  | 		Scheme: scheme, | 
					
						
							|  |  |  | 		Host:   peer.String(), | 
					
						
							|  |  |  | 		Path:   peerRESTPath, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-24 01:51:53 +08:00
										 |  |  | 	restClient := rest.NewClient(serverURL, globalInternodeTransport, newCachedAuthToken()) | 
					
						
							| 
									
										
										
										
											2020-11-11 01:28:23 +08:00
										 |  |  | 	// Use a separate client to avoid recursive calls.
 | 
					
						
							| 
									
										
										
										
											2021-11-24 01:51:53 +08:00
										 |  |  | 	healthClient := rest.NewClient(serverURL, globalInternodeTransport, newCachedAuthToken()) | 
					
						
							| 
									
										
										
										
											2021-06-09 05:09:26 +08:00
										 |  |  | 	healthClient.NoMetrics = true | 
					
						
							| 
									
										
										
										
											2020-11-11 01:28:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-18 05:49:26 +08:00
										 |  |  | 	// Construct a new health function.
 | 
					
						
							|  |  |  | 	restClient.HealthCheckFn = func() bool { | 
					
						
							| 
									
										
										
										
											2021-01-29 05:38:12 +08:00
										 |  |  | 		ctx, cancel := context.WithTimeout(context.Background(), restClient.HealthCheckTimeout) | 
					
						
							| 
									
										
										
										
											2020-11-11 01:28:23 +08:00
										 |  |  | 		defer cancel() | 
					
						
							|  |  |  | 		respBody, err := healthClient.Call(ctx, peerRESTMethodHealth, nil, nil, -1) | 
					
						
							| 
									
										
										
										
											2020-06-18 05:49:26 +08:00
										 |  |  | 		xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2020-11-20 05:53:49 +08:00
										 |  |  | 		return !isNetworkError(err) | 
					
						
							| 
									
										
										
										
											2020-06-18 05:49:26 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-12 13:19:38 +08:00
										 |  |  | 	return &peerRESTClient{host: peer, restClient: restClient} | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-10-10 11:36:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // MonitorBandwidth - send http trace request to peer nodes
 | 
					
						
							| 
									
										
										
										
											2023-01-19 21:22:16 +08:00
										 |  |  | func (client *peerRESTClient) MonitorBandwidth(ctx context.Context, buckets []string) (*bandwidth.BucketBandwidthReport, error) { | 
					
						
							| 
									
										
										
										
											2020-10-10 11:36:00 +08:00
										 |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTBuckets, strings.Join(buckets, ",")) | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodGetBandwidth, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2020-10-10 11:36:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	dec := gob.NewDecoder(respBody) | 
					
						
							| 
									
										
										
										
											2023-01-19 21:22:16 +08:00
										 |  |  | 	var bandwidthReport bandwidth.BucketBandwidthReport | 
					
						
							| 
									
										
										
										
											2020-10-10 11:36:00 +08:00
										 |  |  | 	err = dec.Decode(&bandwidthReport) | 
					
						
							|  |  |  | 	return &bandwidthReport, err | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (client *peerRESTClient) GetPeerMetrics(ctx context.Context) (<-chan Metric, error) { | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodGetPeerMetrics, nil, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	dec := gob.NewDecoder(respBody) | 
					
						
							|  |  |  | 	ch := make(chan Metric) | 
					
						
							|  |  |  | 	go func(ch chan<- Metric) { | 
					
						
							| 
									
										
										
										
											2023-02-09 01:11:16 +08:00
										 |  |  | 		defer func() { | 
					
						
							|  |  |  | 			xhttp.DrainBody(respBody) | 
					
						
							|  |  |  | 			close(ch) | 
					
						
							|  |  |  | 		}() | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 		for { | 
					
						
							|  |  |  | 			var metric Metric | 
					
						
							|  |  |  | 			if err := dec.Decode(&metric); err != nil { | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2023-02-09 01:11:16 +08:00
										 |  |  | 			select { | 
					
						
							|  |  |  | 			case <-ctx.Done(): | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			case ch <- metric: | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	}(ch) | 
					
						
							|  |  |  | 	return ch, nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 13:25:12 +08:00
										 |  |  | func (client *peerRESTClient) GetPeerBucketMetrics(ctx context.Context) (<-chan Metric, error) { | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodGetPeerBucketMetrics, nil, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	dec := gob.NewDecoder(respBody) | 
					
						
							|  |  |  | 	ch := make(chan Metric) | 
					
						
							|  |  |  | 	go func(ch chan<- Metric) { | 
					
						
							|  |  |  | 		defer func() { | 
					
						
							|  |  |  | 			xhttp.DrainBody(respBody) | 
					
						
							|  |  |  | 			close(ch) | 
					
						
							|  |  |  | 		}() | 
					
						
							|  |  |  | 		for { | 
					
						
							|  |  |  | 			var metric Metric | 
					
						
							|  |  |  | 			if err := dec.Decode(&metric); err != nil { | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			select { | 
					
						
							|  |  |  | 			case <-ctx.Done(): | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			case ch <- metric: | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}(ch) | 
					
						
							|  |  |  | 	return ch, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-13 01:12:47 +08:00
										 |  |  | func (client *peerRESTClient) SpeedTest(ctx context.Context, opts speedTestOpts) (SpeedTestResult, error) { | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | 	values := make(url.Values) | 
					
						
							| 
									
										
										
										
											2022-07-13 01:12:47 +08:00
										 |  |  | 	values.Set(peerRESTSize, strconv.Itoa(opts.objectSize)) | 
					
						
							|  |  |  | 	values.Set(peerRESTConcurrent, strconv.Itoa(opts.concurrency)) | 
					
						
							|  |  |  | 	values.Set(peerRESTDuration, opts.duration.String()) | 
					
						
							|  |  |  | 	values.Set(peerRESTStorageClass, opts.storageClass) | 
					
						
							|  |  |  | 	values.Set(peerRESTBucket, opts.bucketName) | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-13 01:12:47 +08:00
										 |  |  | 	respBody, err := client.callWithContext(context.Background(), peerRESTMethodSpeedTest, values, nil, -1) | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-07-13 01:12:47 +08:00
										 |  |  | 		return SpeedTestResult{}, err | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2021-09-01 05:08:23 +08:00
										 |  |  | 	waitReader, err := waitForHTTPResponse(respBody) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-07-13 01:12:47 +08:00
										 |  |  | 		return SpeedTestResult{}, err | 
					
						
							| 
									
										
										
										
											2021-09-01 05:08:23 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-13 01:12:47 +08:00
										 |  |  | 	var result SpeedTestResult | 
					
						
							| 
									
										
										
										
											2021-09-01 05:08:23 +08:00
										 |  |  | 	err = gob.NewDecoder(waitReader).Decode(&result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return result, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if result.Error != "" { | 
					
						
							|  |  |  | 		return result, errors.New(result.Error) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return result, nil | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2021-10-07 07:36:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-02 14:38:05 +08:00
										 |  |  | func (client *peerRESTClient) DriveSpeedTest(ctx context.Context, opts madmin.DriveSpeedTestOpts) (madmin.DriveSpeedTestResult, error) { | 
					
						
							|  |  |  | 	queryVals := make(url.Values) | 
					
						
							|  |  |  | 	if opts.Serial { | 
					
						
							|  |  |  | 		queryVals.Set("serial", "true") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	queryVals.Set("blocksize", strconv.FormatUint(opts.BlockSize, 10)) | 
					
						
							|  |  |  | 	queryVals.Set("filesize", strconv.FormatUint(opts.FileSize, 10)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodDriveSpeedTest, queryVals, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return madmin.DriveSpeedTestResult{}, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2022-02-02 14:38:05 +08:00
										 |  |  | 	waitReader, err := waitForHTTPResponse(respBody) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return madmin.DriveSpeedTestResult{}, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var result madmin.DriveSpeedTestResult | 
					
						
							|  |  |  | 	err = gob.NewDecoder(waitReader).Decode(&result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return result, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if result.Error != "" { | 
					
						
							|  |  |  | 		return result, errors.New(result.Error) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return result, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-07 07:36:31 +08:00
										 |  |  | func (client *peerRESTClient) ReloadSiteReplicationConfig(ctx context.Context) error { | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(context.Background(), peerRESTMethodReloadSiteReplicationConfig, nil, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2021-10-07 07:36:31 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-01-27 06:33:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-14 05:21:55 +08:00
										 |  |  | func (client *peerRESTClient) GetLastDayTierStats(ctx context.Context) (DailyAllTierStats, error) { | 
					
						
							| 
									
										
										
										
											2022-01-27 06:33:10 +08:00
										 |  |  | 	var result map[string]lastDayTierStats | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(context.Background(), peerRESTMethodGetLastDayTierStats, nil, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return result, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2022-01-27 06:33:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	err = gob.NewDecoder(respBody).Decode(&result) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-04-14 05:21:55 +08:00
										 |  |  | 		return DailyAllTierStats{}, err | 
					
						
							| 
									
										
										
										
											2022-01-27 06:33:10 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-04-14 05:21:55 +08:00
										 |  |  | 	return DailyAllTierStats(result), nil | 
					
						
							| 
									
										
										
										
											2022-01-27 06:33:10 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-03-09 01:54:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // DevNull - Used by netperf to pump data to peer
 | 
					
						
							|  |  |  | func (client *peerRESTClient) DevNull(ctx context.Context, r io.Reader) error { | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodDevNull, nil, r, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2022-03-09 01:54:38 +08:00
										 |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Netperf - To initiate netperf on peer
 | 
					
						
							|  |  |  | func (client *peerRESTClient) Netperf(ctx context.Context, duration time.Duration) (madmin.NetperfNodeResult, error) { | 
					
						
							|  |  |  | 	var result madmin.NetperfNodeResult | 
					
						
							|  |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTDuration, duration.String()) | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(context.Background(), peerRESTMethodNetperf, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return result, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-06 03:18:50 +08:00
										 |  |  | 	defer xhttp.DrainBody(respBody) | 
					
						
							| 
									
										
										
										
											2022-03-09 01:54:38 +08:00
										 |  |  | 	err = gob.NewDecoder(respBody).Decode(&result) | 
					
						
							|  |  |  | 	return result, err | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-07-13 14:51:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // GetReplicationMRF - get replication MRF for bucket
 | 
					
						
							|  |  |  | func (client *peerRESTClient) GetReplicationMRF(ctx context.Context, bucket string) (chan madmin.ReplicationMRF, error) { | 
					
						
							|  |  |  | 	values := make(url.Values) | 
					
						
							|  |  |  | 	values.Set(peerRESTBucket, bucket) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	respBody, err := client.callWithContext(ctx, peerRESTMethodGetReplicationMRF, values, nil, -1) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	dec := gob.NewDecoder(respBody) | 
					
						
							|  |  |  | 	ch := make(chan madmin.ReplicationMRF) | 
					
						
							|  |  |  | 	go func(ch chan madmin.ReplicationMRF) { | 
					
						
							|  |  |  | 		defer func() { | 
					
						
							|  |  |  | 			xhttp.DrainBody(respBody) | 
					
						
							|  |  |  | 			close(ch) | 
					
						
							|  |  |  | 		}() | 
					
						
							|  |  |  | 		for { | 
					
						
							|  |  |  | 			var entry madmin.ReplicationMRF | 
					
						
							|  |  |  | 			if err := dec.Decode(&entry); err != nil { | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			select { | 
					
						
							|  |  |  | 			case <-ctx.Done(): | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			case ch <- entry: | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}(ch) | 
					
						
							|  |  |  | 	return ch, nil | 
					
						
							|  |  |  | } |