github.com/minio/madmin-go@v1.7.5/rebalance.go (about)

     1  //
     2  // MinIO Object Storage (c) 2022 MinIO, Inc.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //      http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  //
    16  
    17  package madmin
    18  
    19  import (
    20  	"context"
    21  	"encoding/json"
    22  	"io/ioutil"
    23  	"net/http"
    24  	"time"
    25  )
    26  
    27  // RebalPoolProgress contains metrics like number of objects, versions, etc rebalanced so far.
    28  type RebalPoolProgress struct {
    29  	NumObjects  uint64        `json:"objects"`
    30  	NumVersions uint64        `json:"versions"`
    31  	Bytes       uint64        `json:"bytes"`
    32  	Bucket      string        `json:"bucket"`
    33  	Object      string        `json:"object"`
    34  	Elapsed     time.Duration `json:"elapsed"`
    35  	ETA         time.Duration `json:"eta"`
    36  }
    37  
    38  // RebalancePoolStatus contains metrics of a rebalance operation on a given pool
    39  type RebalancePoolStatus struct {
    40  	ID       int               `json:"id"`                 // Pool index (zero-based)
    41  	Status   string            `json:"status"`             // Active if rebalance is running, empty otherwise
    42  	Used     float64           `json:"used"`               // Percentage used space
    43  	Progress RebalPoolProgress `json:"progress,omitempty"` // is empty when rebalance is not running
    44  }
    45  
    46  // RebalanceStatus contains metrics and progress related information on all pools
    47  type RebalanceStatus struct {
    48  	ID        string                // identifies the ongoing rebalance operation by a uuid
    49  	StoppedAt time.Time             `json:"stoppedAt,omitempty"`
    50  	Pools     []RebalancePoolStatus `json:"pools"` // contains all pools, including inactive
    51  }
    52  
    53  // RebalanceStart starts a rebalance operation if one isn't in progress already
    54  func (adm *AdminClient) RebalanceStart(ctx context.Context) (id string, err error) {
    55  	// Execute POST on /minio/admin/v3/rebalance/start to start a rebalance operation.
    56  	var resp *http.Response
    57  	resp, err = adm.executeMethod(ctx,
    58  		http.MethodPost,
    59  		requestData{relPath: adminAPIPrefix + "/rebalance/start"})
    60  	defer closeResponse(resp)
    61  	if err != nil {
    62  		return id, err
    63  	}
    64  
    65  	if resp.StatusCode != http.StatusOK {
    66  		return id, httpRespToErrorResponse(resp)
    67  	}
    68  
    69  	var rebalInfo struct {
    70  		ID string `json:"id"`
    71  	}
    72  	respBytes, err := ioutil.ReadAll(resp.Body)
    73  	if err != nil {
    74  		return id, err
    75  	}
    76  
    77  	err = json.Unmarshal(respBytes, &rebalInfo)
    78  	if err != nil {
    79  		return id, err
    80  	}
    81  
    82  	return rebalInfo.ID, nil
    83  }
    84  
    85  func (adm *AdminClient) RebalanceStatus(ctx context.Context) (r RebalanceStatus, err error) {
    86  	// Execute GET on /minio/admin/v3/rebalance/status to get status of an ongoing rebalance operation.
    87  	resp, err := adm.executeMethod(ctx,
    88  		http.MethodGet,
    89  		requestData{relPath: adminAPIPrefix + "/rebalance/status"})
    90  	defer closeResponse(resp)
    91  	if err != nil {
    92  		return r, err
    93  	}
    94  
    95  	if resp.StatusCode != http.StatusOK {
    96  		return r, httpRespToErrorResponse(resp)
    97  	}
    98  
    99  	respBytes, err := ioutil.ReadAll(resp.Body)
   100  	if err != nil {
   101  		return r, err
   102  	}
   103  
   104  	err = json.Unmarshal(respBytes, &r)
   105  	if err != nil {
   106  		return r, err
   107  	}
   108  
   109  	return r, nil
   110  }
   111  
   112  func (adm *AdminClient) RebalanceStop(ctx context.Context) error {
   113  	// Execute POST on /minio/admin/v3/rebalance/stop to stop an ongoing rebalance operation.
   114  	resp, err := adm.executeMethod(ctx,
   115  		http.MethodPost,
   116  		requestData{relPath: adminAPIPrefix + "/rebalance/stop"})
   117  	defer closeResponse(resp)
   118  	if err != nil {
   119  		return err
   120  	}
   121  
   122  	if resp.StatusCode != http.StatusOK {
   123  		return httpRespToErrorResponse(resp)
   124  	}
   125  
   126  	return nil
   127  }