mirror of
https://github.com/minio/minio.git
synced 2024-12-25 14:45:54 -05:00
Return possible states a heal operation (#4045)
This commit is contained in:
parent
5f065e2a96
commit
ca64b86112
@ -630,9 +630,40 @@ func isDryRun(qval url.Values) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type healObjectResult struct {
|
// healResult - represents result of a heal operation like
|
||||||
HealedCount int
|
// heal-object, heal-upload.
|
||||||
OfflineCount int
|
type healResult struct {
|
||||||
|
State healState `json:"state"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// healState - different states of heal operation
|
||||||
|
type healState int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// healNone - none of the disks healed
|
||||||
|
healNone healState = iota
|
||||||
|
// healPartial - some disks were healed, others were offline
|
||||||
|
healPartial
|
||||||
|
// healOK - all disks were healed
|
||||||
|
healOK
|
||||||
|
)
|
||||||
|
|
||||||
|
// newHealResult - returns healResult given number of disks healed and
|
||||||
|
// number of disks offline
|
||||||
|
func newHealResult(numHealedDisks, numOfflineDisks int) healResult {
|
||||||
|
var state healState
|
||||||
|
switch {
|
||||||
|
case numHealedDisks == 0:
|
||||||
|
state = healNone
|
||||||
|
|
||||||
|
case numOfflineDisks > 0:
|
||||||
|
state = healPartial
|
||||||
|
|
||||||
|
default:
|
||||||
|
state = healOK
|
||||||
|
}
|
||||||
|
|
||||||
|
return healResult{State: state}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HealObjectHandler - POST /?heal&bucket=mybucket&object=myobject&dry-run
|
// HealObjectHandler - POST /?heal&bucket=mybucket&object=myobject&dry-run
|
||||||
@ -683,10 +714,7 @@ func (adminAPI adminAPIHandlers) HealObjectHandler(w http.ResponseWriter, r *htt
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonBytes, err := json.Marshal(healObjectResult{
|
jsonBytes, err := json.Marshal(newHealResult(numHealedDisks, numOfflineDisks))
|
||||||
HealedCount: numHealedDisks,
|
|
||||||
OfflineCount: numOfflineDisks,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
|
||||||
return
|
return
|
||||||
@ -761,10 +789,7 @@ func (adminAPI adminAPIHandlers) HealUploadHandler(w http.ResponseWriter, r *htt
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonBytes, err := json.Marshal(healObjectResult{
|
jsonBytes, err := json.Marshal(newHealResult(numHealedDisks, numOfflineDisks))
|
||||||
HealedCount: numHealedDisks,
|
|
||||||
OfflineCount: numOfflineDisks,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(err), r.URL)
|
||||||
return
|
return
|
||||||
|
@ -1586,3 +1586,29 @@ func TestListHealUploadsHandler(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test for newHealResult helper function.
|
||||||
|
func TestNewHealResult(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
healedDisks int
|
||||||
|
offlineDisks int
|
||||||
|
state healState
|
||||||
|
}{
|
||||||
|
// 1. No disks healed, no disks offline.
|
||||||
|
{0, 0, healNone},
|
||||||
|
// 2. No disks healed, non-zero disks offline.
|
||||||
|
{0, 1, healNone},
|
||||||
|
// 3. Non-zero disks healed, no disks offline.
|
||||||
|
{1, 0, healOK},
|
||||||
|
// 4. Non-zero disks healed, non-zero disks offline.
|
||||||
|
{1, 1, healPartial},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range testCases {
|
||||||
|
actual := newHealResult(test.healedDisks, test.offlineDisks)
|
||||||
|
if actual.State != test.state {
|
||||||
|
t.Errorf("Test %d: Expected %v but received %v", i+1,
|
||||||
|
test.state, actual.State)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -336,12 +336,19 @@ func healObject(storageDisks []StorageAPI, bucket string, object string, quorum
|
|||||||
return 0, 0, toObjectErr(aErr, bucket, object)
|
return 0, 0, toObjectErr(aErr, bucket, object)
|
||||||
}
|
}
|
||||||
|
|
||||||
numAvailableDisks := 0
|
// Number of disks which don't serve data.
|
||||||
numOfflineDisks := 0
|
numOfflineDisks := 0
|
||||||
for index, disk := range availableDisks {
|
for index, disk := range storageDisks {
|
||||||
switch {
|
switch {
|
||||||
case disk == nil, errs[index] == errDiskNotFound:
|
case disk == nil, errs[index] == errDiskNotFound:
|
||||||
numOfflineDisks++
|
numOfflineDisks++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number of disks which have all parts of the given object.
|
||||||
|
numAvailableDisks := 0
|
||||||
|
for _, disk := range availableDisks {
|
||||||
|
switch {
|
||||||
case disk != nil:
|
case disk != nil:
|
||||||
numAvailableDisks++
|
numAvailableDisks++
|
||||||
}
|
}
|
||||||
@ -357,6 +364,8 @@ func healObject(storageDisks []StorageAPI, bucket string, object string, quorum
|
|||||||
outDatedDisks := outDatedDisks(storageDisks, availableDisks, errs, partsMetadata,
|
outDatedDisks := outDatedDisks(storageDisks, availableDisks, errs, partsMetadata,
|
||||||
bucket, object)
|
bucket, object)
|
||||||
|
|
||||||
|
// Number of disks that had outdated content of the given
|
||||||
|
// object and are online to be healed.
|
||||||
numHealedDisks := 0
|
numHealedDisks := 0
|
||||||
for _, disk := range outDatedDisks {
|
for _, disk := range outDatedDisks {
|
||||||
if disk != nil {
|
if disk != nil {
|
||||||
|
@ -245,6 +245,18 @@ __Example__
|
|||||||
### HealObject(bucket, object string, isDryRun bool) (HealResult, error)
|
### HealObject(bucket, object string, isDryRun bool) (HealResult, error)
|
||||||
If object is successfully healed returns nil, otherwise returns error indicating the reason for failure. If isDryRun is true, then the object is not healed, but heal object request is validated by the server. e.g, if the object exists, if object name is valid etc.
|
If object is successfully healed returns nil, otherwise returns error indicating the reason for failure. If isDryRun is true, then the object is not healed, but heal object request is validated by the server. e.g, if the object exists, if object name is valid etc.
|
||||||
|
|
||||||
|
| Param | Type | Description |
|
||||||
|
|---|---|---|
|
||||||
|
|`h.State` | _HealState_ | Represents the result of heal operation. It could be one of `HealNone`, `HealPartial` or `HealOK`. |
|
||||||
|
|
||||||
|
|
||||||
|
| Value | Description |
|
||||||
|
|---|---|
|
||||||
|
|`HealNone` | Object/Upload wasn't healed on any of the disks |
|
||||||
|
|`HealPartial` | Object/Upload was healed on some of the disks needing heal |
|
||||||
|
| `HealOK` | Object/Upload was healed on all the disks needing heal |
|
||||||
|
|
||||||
|
|
||||||
__Example__
|
__Example__
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
@ -327,6 +339,17 @@ __Example__
|
|||||||
### HealUpload(bucket, object, uploadID string, isDryRun bool) (HealResult, error)
|
### HealUpload(bucket, object, uploadID string, isDryRun bool) (HealResult, error)
|
||||||
If upload is successfully healed returns nil, otherwise returns error indicating the reason for failure. If isDryRun is true, then the upload is not healed, but heal upload request is validated by the server. e.g, if the upload exists, if upload name is valid etc.
|
If upload is successfully healed returns nil, otherwise returns error indicating the reason for failure. If isDryRun is true, then the upload is not healed, but heal upload request is validated by the server. e.g, if the upload exists, if upload name is valid etc.
|
||||||
|
|
||||||
|
| Param | Type | Description |
|
||||||
|
|---|---|---|
|
||||||
|
|`h.State` | _HealState_ | Represents the result of heal operation. It could be one of `HealNone`, `HealPartial` or `HealOK`. |
|
||||||
|
|
||||||
|
|
||||||
|
| Value | Description |
|
||||||
|
|---|---|
|
||||||
|
| `HealNone` | Object/Upload wasn't healed on any of the disks |
|
||||||
|
| `HealPartial` | Object/Upload was healed on some of the disks needing heal |
|
||||||
|
| `HealOK` | Object/Upload was healed on all the disks needing heal |
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
isDryRun = false
|
isDryRun = false
|
||||||
healResult, err := madmClnt.HealUpload("mybucket", "myobject", "myUploadID", isDryRun)
|
healResult, err := madmClnt.HealUpload("mybucket", "myobject", "myUploadID", isDryRun)
|
||||||
|
@ -494,10 +494,21 @@ func (adm *AdminClient) HealUpload(bucket, object, uploadID string, dryrun bool)
|
|||||||
|
|
||||||
// HealResult - represents result of heal-object admin API.
|
// HealResult - represents result of heal-object admin API.
|
||||||
type HealResult struct {
|
type HealResult struct {
|
||||||
HealedCount int // number of disks that were healed.
|
State HealState `json:"state"`
|
||||||
OfflineCount int // number of disks that needed healing but were offline.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HealState - different states of heal operation
|
||||||
|
type HealState int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// HealNone - none of the disks healed
|
||||||
|
HealNone HealState = iota
|
||||||
|
// HealPartial - some disks were healed, others were offline
|
||||||
|
HealPartial
|
||||||
|
// HealOK - all disks were healed
|
||||||
|
HealOK
|
||||||
|
)
|
||||||
|
|
||||||
// HealObject - Heal the given object.
|
// HealObject - Heal the given object.
|
||||||
func (adm *AdminClient) HealObject(bucket, object string, dryrun bool) (HealResult, error) {
|
func (adm *AdminClient) HealObject(bucket, object string, dryrun bool) (HealResult, error) {
|
||||||
// Construct query params.
|
// Construct query params.
|
||||||
|
Loading…
Reference in New Issue
Block a user