github.com/minio/madmin-go/v3@v3.0.51/decommission-commands.go (about)

     1  //
     2  // Copyright (c) 2015-2022 MinIO, Inc.
     3  //
     4  // This file is part of MinIO Object Storage stack
     5  //
     6  // This program is free software: you can redistribute it and/or modify
     7  // it under the terms of the GNU Affero General Public License as
     8  // published by the Free Software Foundation, either version 3 of the
     9  // License, or (at your option) any later version.
    10  //
    11  // This program is distributed in the hope that it will be useful,
    12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  // GNU Affero General Public License for more details.
    15  //
    16  // You should have received a copy of the GNU Affero General Public License
    17  // along with this program. If not, see <http://www.gnu.org/licenses/>.
    18  //
    19  
    20  package madmin
    21  
    22  import (
    23  	"context"
    24  	"encoding/json"
    25  	"net/http"
    26  	"net/url"
    27  	"time"
    28  )
    29  
    30  // PoolDecommissionInfo currently draining information
    31  type PoolDecommissionInfo struct {
    32  	StartTime   time.Time `json:"startTime"`
    33  	StartSize   int64     `json:"startSize"`
    34  	TotalSize   int64     `json:"totalSize"`
    35  	CurrentSize int64     `json:"currentSize"`
    36  	Complete    bool      `json:"complete"`
    37  	Failed      bool      `json:"failed"`
    38  	Canceled    bool      `json:"canceled"`
    39  
    40  	ObjectsDecommissioned     int64 `json:"objectsDecommissioned"`
    41  	ObjectsDecommissionFailed int64 `json:"objectsDecommissionedFailed"`
    42  	BytesDone                 int64 `json:"bytesDecommissioned"`
    43  	BytesFailed               int64 `json:"bytesDecommissionedFailed"`
    44  }
    45  
    46  // PoolStatus captures current pool status
    47  type PoolStatus struct {
    48  	ID           int                   `json:"id"`
    49  	CmdLine      string                `json:"cmdline"`
    50  	LastUpdate   time.Time             `json:"lastUpdate"`
    51  	Decommission *PoolDecommissionInfo `json:"decommissionInfo,omitempty"`
    52  }
    53  
    54  // DecommissionPool - starts moving data from specified pool to all other existing pools.
    55  // Decommissioning if successfully started this function will return `nil`, to check
    56  // for on-going draining cycle use StatusPool.
    57  func (adm *AdminClient) DecommissionPool(ctx context.Context, pool string) error {
    58  	values := url.Values{}
    59  	values.Set("pool", pool)
    60  	resp, err := adm.executeMethod(ctx, http.MethodPost, requestData{
    61  		// POST <endpoint>/<admin-API>/pools/decommission?pool=http://server{1...4}/disk{1...4}
    62  		relPath:     adminAPIPrefix + "/pools/decommission",
    63  		queryValues: values,
    64  	})
    65  	if err != nil {
    66  		return err
    67  	}
    68  	defer closeResponse(resp)
    69  	if resp.StatusCode != http.StatusOK {
    70  		return httpRespToErrorResponse(resp)
    71  	}
    72  	return nil
    73  }
    74  
    75  // CancelDecommissionPool - cancels an on-going decommissioning process,
    76  // this automatically makes the pool available for writing once canceled.
    77  func (adm *AdminClient) CancelDecommissionPool(ctx context.Context, pool string) error {
    78  	values := url.Values{}
    79  	values.Set("pool", pool)
    80  	resp, err := adm.executeMethod(ctx, http.MethodPost, requestData{
    81  		// POST <endpoint>/<admin-API>/pools/cancel?pool=http://server{1...4}/disk{1...4}
    82  		relPath:     adminAPIPrefix + "/pools/cancel",
    83  		queryValues: values,
    84  	})
    85  	if err != nil {
    86  		return err
    87  	}
    88  	defer closeResponse(resp)
    89  	if resp.StatusCode != http.StatusOK {
    90  		return httpRespToErrorResponse(resp)
    91  	}
    92  	return nil
    93  }
    94  
    95  // StatusPool return current status about pool, reports any draining activity in progress
    96  // and elapsed time.
    97  func (adm *AdminClient) StatusPool(ctx context.Context, pool string) (PoolStatus, error) {
    98  	values := url.Values{}
    99  	values.Set("pool", pool)
   100  	resp, err := adm.executeMethod(ctx, http.MethodGet, requestData{
   101  		// GET <endpoint>/<admin-API>/pools/status?pool=http://server{1...4}/disk{1...4}
   102  		relPath:     adminAPIPrefix + "/pools/status",
   103  		queryValues: values,
   104  	})
   105  	if err != nil {
   106  		return PoolStatus{}, err
   107  	}
   108  	defer closeResponse(resp)
   109  
   110  	if resp.StatusCode != http.StatusOK {
   111  		return PoolStatus{}, httpRespToErrorResponse(resp)
   112  	}
   113  
   114  	var info PoolStatus
   115  	if err = json.NewDecoder(resp.Body).Decode(&info); err != nil {
   116  		return PoolStatus{}, err
   117  	}
   118  
   119  	return info, nil
   120  }
   121  
   122  // ListPoolsStatus returns list of pools currently configured and being used
   123  // on the cluster.
   124  func (adm *AdminClient) ListPoolsStatus(ctx context.Context) ([]PoolStatus, error) {
   125  	resp, err := adm.executeMethod(ctx, http.MethodGet, requestData{
   126  		relPath: adminAPIPrefix + "/pools/list", // GET <endpoint>/<admin-API>/pools/list
   127  	})
   128  	if err != nil {
   129  		return nil, err
   130  	}
   131  	defer closeResponse(resp)
   132  	if resp.StatusCode != http.StatusOK {
   133  		return nil, httpRespToErrorResponse(resp)
   134  	}
   135  	var pools []PoolStatus
   136  	if err = json.NewDecoder(resp.Body).Decode(&pools); err != nil {
   137  		return nil, err
   138  	}
   139  	return pools, nil
   140  }