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 }