diff --git a/doc/endpoints.md b/doc/endpoints.md index 354dfa94e..294f533f1 100644 --- a/doc/endpoints.md +++ b/doc/endpoints.md @@ -71,8 +71,6 @@ BitrotEnable | POST | /volumes/{volname}/bitrot/enable | [](https://godoc.org/gi BitrotDisable | POST | /volumes/{volname}/bitrot/disable | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) ScrubOndemand | POST | /volumes/{volname}/bitrot/scrubondemand | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) ScrubStatus | GET | /volumes/{volname}/bitrot/scrubstatus | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) -QuotaEnable | POST | /quota/{volname} | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) -QuotaDisable | DELETE | /quota/{volname} | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) QuotaList | GET | /quota/{volname}/limit | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) QuotaLimit | POST | /quota/{volname}/limit | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) QuotaRemove | DELETE | /quota/{volname}/limit | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) @@ -81,14 +79,16 @@ WebhookTest | POST | /events/webhook/test | [Webhook](https://godoc.org/github.c WebhookDelete | DELETE | /events/webhook | [WebhookDel](https://godoc.org/github.com/gluster/glusterd2/pkg/api#WebhookDel) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) WebhookList | GET | /events/webhook | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [WebhookList](https://godoc.org/github.com/gluster/glusterd2/pkg/api#WebhookList) EventsList | GET | /events | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [Event](https://godoc.org/github.com/gluster/glusterd2/pkg/api#Event) -SelfHealInfo | GET | /volumes/{name}/{opts}/heal-info | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [BrickHealInfo](https://godoc.org/github.com/gluster/glusterd2/pkg/api#BrickHealInfo) -SelfHealInfo2 | GET | /volumes/{name}/heal-info | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [BrickHealInfo](https://godoc.org/github.com/gluster/glusterd2/pkg/api#BrickHealInfo) +SelfHealInfo | GET | /volumes/{volname}/{opts}/heal-info | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [BrickHealInfo](https://godoc.org/github.com/gluster/glusterd2/pkg/api#BrickHealInfo) +SelfHealInfo2 | GET | /volumes/{volname}/heal-info | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [BrickHealInfo](https://godoc.org/github.com/gluster/glusterd2/pkg/api#BrickHealInfo) +SelfHeal | POST | /volumes/{volname}/heal | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) DeviceAdd | POST | /devices/{peerid} | [AddDeviceReq](https://godoc.org/github.com/gluster/glusterd2/pkg/api#AddDeviceReq) | [AddDeviceResp](https://godoc.org/github.com/gluster/glusterd2/pkg/api#AddDeviceResp) DeviceList | GET | /devices/{peerid} | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [ListDeviceResp](https://godoc.org/github.com/gluster/glusterd2/pkg/api#ListDeviceResp) +DeviceEdit | POST | /devices/{peerid} | [EditDeviceReq](https://godoc.org/github.com/gluster/glusterd2/pkg/api#EditDeviceReq) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) ListAllDevices | GET | /devices | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [ListDeviceResp](https://godoc.org/github.com/gluster/glusterd2/pkg/api#ListDeviceResp) RebalanceStart | POST | /volumes/{volname}/rebalance/start | [StartReq](https://godoc.org/github.com/gluster/glusterd2/pkg/api#StartReq) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) RebalanceStop | POST | /volumes/{volname}/rebalance/stop | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) -RebalanceStatus | GET | /volumes/{volname}/rebalance | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) +RebalanceStatus | GET | /volumes/{volname}/rebalance | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [RebalStatus](https://godoc.org/github.com/gluster/glusterd2/pkg/api#RebalStatus) SmartVolumeCreate | POST | /smartvol | [VolCreateReq](https://godoc.org/github.com/gluster/glusterd2/pkg/api#VolCreateReq) | [VolumeCreateResp](https://godoc.org/github.com/gluster/glusterd2/pkg/api#VolumeCreateResp) Statedump | GET | /statedump | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) List Endpoints | GET | /endpoints | [](https://godoc.org/github.com/gluster/glusterd2/pkg/api#) | [ListEndpointsResp](https://godoc.org/github.com/gluster/glusterd2/pkg/api#ListEndpointsResp) diff --git a/glustercli/cmd/rebalance.go b/glustercli/cmd/rebalance.go new file mode 100644 index 000000000..6c8c37f69 --- /dev/null +++ b/glustercli/cmd/rebalance.go @@ -0,0 +1,76 @@ +package cmd + +import ( + "fmt" + + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +const ( + helpRebalanceCmd = "Gluster Rebalance" + helpRebalanceStartCmd = "Start rebalance operation for gluster volume" + helpRebalanceStatusCmd = "Status of rebalance operation" + helpRebalanceStopCmd = "Stop rebalance operation" +) + +var ( + flagRebalanceStartCmdForce bool + flagRebalanceStartCmdFixLayout bool +) + +var rebalanceCmd = &cobra.Command{ + Use: "volume rebalance", + Short: helpRebalanceCmd, +} + +func init() { + + // Rebalance Start + rebalanceStartCmd.Flags().BoolVar(&flagRebalanceStartCmdForce, "force", false, "Force") + rebalanceStartCmd.Flags().BoolVar(&flagRebalanceStartCmdFixLayout, "fixlayout", false, "FixLayout") + rebalanceCmd.AddCommand(rebalanceStartCmd) + + RootCmd.AddCommand(rebalanceCmd) +} + +var rebalanceStartCmd = &cobra.Command{ + Use: " start [flags]", + Short: helpRebalanceStartCmd, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + volname := cmd.Flags().Args()[0] + var err error + if flagRebalanceStartCmdForce { + err = client.RebalanceStart(volname, "force") + } else if flagRebalanceStartCmdFixLayout { + err = client.RebalanceStart(volname, "fix-layout") + } else { + err = client.RebalanceStart(volname, "") + } + if err != nil { + if verbose { + log.WithError(err).WithField("volume", volname).Error("rebalance start failed") + } + failure("rebalance start failed", err, 1) + } + fmt.Printf("Rebalance for %s started successfully\n", volname) + }, +} + +var rebalanceStopCmd = &cobra.Command{ + Use: " stop", + Short: helpRebalanceStopCmd, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + volname := cmd.Flags().Args()[0] + err := client.RebalanceStop(volname) + if err != nil { + if verbose { + log.WithError(err).WithField("volume", volname).Error("Rebalance stop failed") + } + failure("rebalance start failed", err, 1) + } + fmt.Printf("Rebalance for %s stopped successfully\n", volname) + }, +} diff --git a/glustercli/cmd/volume.go b/glustercli/cmd/volume.go index c17859dcc..d1e652422 100644 --- a/glustercli/cmd/volume.go +++ b/glustercli/cmd/volume.go @@ -183,10 +183,7 @@ var volumeStartCmd = &cobra.Command{ err := client.VolumeStart(volname, flagStartCmdForce) if err != nil { if verbose { - log.WithFields(log.Fields{ - "volume": volname, - "error": err.Error(), - }).Error("volume start failed") + log.WithError(err).WithField("volume", volname).Error("volume start failed") } failure("volume start failed", err, 1) } @@ -203,10 +200,7 @@ var volumeStopCmd = &cobra.Command{ err := client.VolumeStop(volname) if err != nil { if verbose { - log.WithFields(log.Fields{ - "volume": volname, - "error": err.Error(), - }).Error("volume stop failed") + log.WithError(err).WithField("volume", volname).Error("volume stop failed") } failure("Volume stop failed", err, 1) } @@ -223,10 +217,7 @@ var volumeDeleteCmd = &cobra.Command{ err := client.VolumeDelete(volname) if err != nil { if verbose { - log.WithFields(log.Fields{ - "volume": volname, - "error": err.Error(), - }).Error("volume deletion failed") + log.WithError(err).WithField("volume", volname).Error("volume deletion failed") } failure("Volume deletion failed", err, 1) } @@ -380,9 +371,7 @@ var volumeInfoCmd = &cobra.Command{ err := volumeInfoHandler2(cmd, true) if err != nil { if verbose { - log.WithFields(log.Fields{ - "error": err.Error(), - }).Error("error getting volumes list") + log.WithError(err).Error("error getting volumes list") } failure("Error getting Volumes list", err, 1) } @@ -397,9 +386,7 @@ var volumeListCmd = &cobra.Command{ err := volumeInfoHandler2(cmd, false) if err != nil { if verbose { - log.WithFields(log.Fields{ - "error": err.Error(), - }).Error("error getting volumes list") + log.WithError(err).Error("error getting volumes list") } failure("Error getting Volumes list", err, 1) } diff --git a/pkg/restclient/rebalance.go b/pkg/restclient/rebalance.go new file mode 100644 index 000000000..d76ef518d --- /dev/null +++ b/pkg/restclient/rebalance.go @@ -0,0 +1,23 @@ +package restclient + +import ( + "fmt" + "net/http" + + rebalanceapi "github.com/gluster/glusterd2/plugins/rebalance/api" +) + +// RebalanceStart starts rebalance process for given volume +func (c *Client) RebalanceStart(volname string, option string) error { + req := rebalanceapi.StartReq{ + Option: option, + } + url := fmt.Sprintf("/v1/volumes/%s/rebalance/start", volname) + return c.post(url, req, http.StatusOK, nil) +} + +// RebalanceStop stops rebalance process for given volume +func (c *Client) RebalanceStop(volname string) error { + url := fmt.Sprintf("/v1/volumes/%s/rebalance/stop", volname) + return c.post(url, nil, http.StatusOK, nil) +} diff --git a/plugins/rebalance/api/req_resp.go b/plugins/rebalance/api/req_resp.go index cc1e1a599..b5e27c334 100644 --- a/plugins/rebalance/api/req_resp.go +++ b/plugins/rebalance/api/req_resp.go @@ -64,6 +64,7 @@ type RebalInfo struct { // RebalStatus represents the rebalance status response type RebalStatus struct { Volname string `json:"volume"` + State Status `json:"state"` RebalanceID uuid.UUID `json:"rebalance-id"` Nodes []RebalNodeStatus `json:"nodes-status"` } diff --git a/plugins/rebalance/errors.go b/plugins/rebalance/errors.go index 9f42a6056..68a6f7b1d 100644 --- a/plugins/rebalance/errors.go +++ b/plugins/rebalance/errors.go @@ -7,6 +7,8 @@ import ( var ( // ErrVolNotDistribute : Cannot run rebalance on a non distribute volume ErrVolNotDistribute = errors.New("not a distribute volume") + // ErrRebalanceAlreadyStarted : Rebalance already started on the volume + ErrRebalanceAlreadyStarted = errors.New("rebalance already started") // ErrRebalanceNotStarted : Rebalance not started on the volume ErrRebalanceNotStarted = errors.New("rebalance not started") // ErrRebalanceInvalidOption : Invalid option provided to the rebalance start command diff --git a/plugins/rebalance/init.go b/plugins/rebalance/init.go index 24339324f..a1e6c6ac2 100644 --- a/plugins/rebalance/init.go +++ b/plugins/rebalance/init.go @@ -25,22 +25,20 @@ func (p *Plugin) RestRoutes() route.Routes { Pattern: "/volumes/{volname}/rebalance/start", Version: 1, RequestType: utils.GetTypeString((*rebalanceapi.StartReq)(nil)), - // ResponseType: utils.GetTypeString((*rebalanceapi.RebalInfo)(nil)), HandlerFunc: rebalanceStartHandler}, route.Route{ - Name: "RebalanceStop", - Method: "POST", - Pattern: "/volumes/{volname}/rebalance/stop", - Version: 1, - // ResponseType: utils.GetTypeString((*rebalanceapi.RebalInfo)(nil)), + Name: "RebalanceStop", + Method: "POST", + Pattern: "/volumes/{volname}/rebalance/stop", + Version: 1, HandlerFunc: rebalanceStopHandler}, route.Route{ - Name: "RebalanceStatus", - Method: "GET", - Pattern: "/volumes/{volname}/rebalance", - Version: 1, - // ResponseType: utils.GetTypeString((*rebalanceapi.RebalInfo)(nil)), - HandlerFunc: rebalanceStatusHandler}, + Name: "RebalanceStatus", + Method: "GET", + Pattern: "/volumes/{volname}/rebalance", + Version: 1, + ResponseType: utils.GetTypeString((*rebalanceapi.RebalStatus)(nil)), + HandlerFunc: rebalanceStatusHandler}, } } diff --git a/plugins/rebalance/rest.go b/plugins/rebalance/rest.go index 9f35d625d..5524aee9a 100644 --- a/plugins/rebalance/rest.go +++ b/plugins/rebalance/rest.go @@ -44,14 +44,18 @@ func rebalanceStartHandler(w http.ResponseWriter, r *http.Request) { return } - rebalinfo := createRebalanceInfo(volname, &req) - if rebalinfo == nil { - logger.WithError(err).Error("failed to create Rebalance info") - restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) - return + rebalInfo, err := GetRebalanceInfo(volname) + if err == nil { + if rebalInfo.State == rebalanceapi.Started { + log.WithError(err).WithField("volume-name", volname).Error("Rebalance process has already been started.") + restutils.SendHTTPError(ctx, w, http.StatusBadRequest, ErrRebalanceAlreadyStarted) + return + } } - if rebalinfo.Cmd == rebalanceapi.CmdNone { + rebalInfo = createRebalanceInfo(volname, &req) + + if rebalInfo.Cmd == rebalanceapi.CmdNone { restutils.SendHTTPError(ctx, w, http.StatusBadRequest, ErrRebalanceInvalidOption) return } @@ -100,14 +104,14 @@ func rebalanceStartHandler(w http.ResponseWriter, r *http.Request) { err = txn.Ctx.Set("volname", volname) if err != nil { - logger.WithError(err).Error("failed to set volname in transaction context") + logger.WithError(err).WithField("key", "volname").Error("failed to set volname in transaction context") restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) return } - err = txn.Ctx.Set("rinfo", rebalinfo) + err = txn.Ctx.Set("rinfo", rebalInfo) if err != nil { - logger.WithError(err).Error("failed to set rebalance info in transaction context") + logger.WithError(err).WithField("key", "rinfo").Error("failed to set rebalance info in transaction context") restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) return } @@ -118,25 +122,14 @@ func rebalanceStartHandler(w http.ResponseWriter, r *http.Request) { * rebalance process is one per node per volume. * Need to handle scenarios where process is started in * few nodes and failed in few others */ - logger.WithFields(log.Fields{ - "error": err.Error(), - "volname": volname, - }).Error("failed to start rebalance on volume") - restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) + logger.WithError(err).WithField("volname", volname).Error("failed to start rebalance on volume") + status, err := restutils.ErrToStatusCode(err) + restutils.SendHTTPError(ctx, w, status, err) return } - rebalinfo, err = GetRebalanceInfo(volname) - if err != nil { - logger.WithFields(log.Fields{ - "error": err.Error(), - "volname": volname, - }).Error("failed to get the rebalance info for volume") - } - - logger.WithField("volname", rebalinfo.Volname).Info("rebalance started") - - restutils.SendHTTPResponse(ctx, w, http.StatusOK, rebalinfo.RebalanceID) + logger.WithField("volname", rebalInfo.Volname).Info("rebalance started") + restutils.SendHTTPResponse(ctx, w, http.StatusOK, nil) } func rebalanceStopHandler(w http.ResponseWriter, r *http.Request) { @@ -162,15 +155,15 @@ func rebalanceStopHandler(w http.ResponseWriter, r *http.Request) { return } - rebalinfo, err := GetRebalanceInfo(volname) + rebalInfo, err := GetRebalanceInfo(volname) if err != nil { - restutils.SendHTTPError(r.Context(), w, http.StatusBadRequest, ErrRebalanceNotStarted) + restutils.SendHTTPError(ctx, w, http.StatusBadRequest, err) return } // Check whether the rebalance state is started - if rebalinfo.State != rebalanceapi.Started { - restutils.SendHTTPError(r.Context(), w, http.StatusBadRequest, ErrRebalanceNotStarted) + if rebalInfo.State != rebalanceapi.Started { + restutils.SendHTTPError(ctx, w, http.StatusBadRequest, ErrRebalanceNotStarted) return } @@ -188,34 +181,30 @@ func rebalanceStopHandler(w http.ResponseWriter, r *http.Request) { err = txn.Ctx.Set("volname", volname) if err != nil { - logger.WithError(err).Error("failed to set volname in transaction context") - restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err.Error()) + logger.WithError(err).WithField("key", "volname").Error("failed to set volname in transaction context") + restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) return } - rebalinfo.Volname = volname - rebalinfo.State = rebalanceapi.Stopped - rebalinfo.Cmd = rebalanceapi.CmdStop + rebalInfo.State = rebalanceapi.Stopped + rebalInfo.Cmd = rebalanceapi.CmdStop - err = txn.Ctx.Set("rinfo", rebalinfo) + err = txn.Ctx.Set("rinfo", rebalInfo) if err != nil { - logger.WithError(err).Error("failed to set rebalance info in transaction context") - restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err.Error()) + logger.WithError(err).WithField("key", "rebalInfo").Error("failed to set rebalance info in transaction context") + restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) return } err = txn.Do() if err != nil { - logger.WithFields(log.Fields{ - "error": err.Error(), - "volname": volname, - }).Error("failed to stop rebalance on volume") - restutils.SendHTTPError(r.Context(), w, http.StatusInternalServerError, err.Error()) + logger.WithError(err).WithField("volname", volname).Error("failed to stop rebalance on volume") + restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) return } - logger.WithField("volname", rebalinfo.Volname).Info("rebalance stopped") - restutils.SendHTTPResponse(r.Context(), w, http.StatusOK, rebalinfo) + logger.WithField("volname", rebalInfo.Volname).Info("rebalance stopped") + restutils.SendHTTPResponse(ctx, w, http.StatusOK, nil) } func rebalanceStatusHandler(w http.ResponseWriter, r *http.Request) { @@ -241,16 +230,16 @@ func rebalanceStatusHandler(w http.ResponseWriter, r *http.Request) { return } - rebalinfo, err := GetRebalanceInfo(volname) + rebalInfo, err := GetRebalanceInfo(volname) if err != nil { - restutils.SendHTTPError(ctx, w, http.StatusNotFound, err.Error()) + restutils.SendHTTPError(ctx, w, http.StatusNotFound, err) return } err = txn.Ctx.Set("volname", volname) if err != nil { - logger.WithError(err).Error("failed to set volname in transaction context") - restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err.Error()) + logger.WithError(err).WithField("key", "volname").Error("failed to set volname in transaction context") + restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) return } @@ -266,57 +255,55 @@ func rebalanceStatusHandler(w http.ResponseWriter, r *http.Request) { }, } - err = txn.Ctx.Set("rinfo", rebalinfo) + err = txn.Ctx.Set("rinfo", rebalInfo) if err != nil { - logger.WithError(err).Error("failed to set rebalance info in transaction context") - restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err.Error()) + logger.WithError(err).WithField("key", "rinfo").Error("failed to set rebalance info in transaction context") + restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) return } err = txn.Do() if err != nil { - logger.WithFields(log.Fields{ - "error": err.Error(), - "volname": volname, - }).Error("failed to query rebalance status for volume") + logger.WithError(err).WithField("volname", volname).Error("failed to query rebalance status for volume") + return } response, err := createRebalanceStatusResp(txn.Ctx, vol) if err != nil { - errMsg := "Failed to create rebalance status response" - logger.WithField("error", err.Error()).Error("rebalanceStatusHandler:" + errMsg) - restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, - errMsg) + errMsg := "failed to create rebalance status response" + logger.WithError(err).Error("rebalanceStatusHandler:" + errMsg) + restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, errMsg) return } - restutils.SendHTTPResponse(r.Context(), w, http.StatusOK, response) + restutils.SendHTTPResponse(ctx, w, http.StatusOK, response) } -func createRebalanceStatusResp(ctx transaction.TxnCtx, volinfo *volume.Volinfo) (*rebalanceapi.RebalStatus, error) { +func createRebalanceStatusResp(ctx transaction.TxnCtx, volInfo *volume.Volinfo) (*rebalanceapi.RebalStatus, error) { var ( resp rebalanceapi.RebalStatus tmp rebalanceapi.RebalNodeStatus - rebalinfo rebalanceapi.RebalInfo + rebalInfo rebalanceapi.RebalInfo ) - err := ctx.Get("rinfo", &rebalinfo) + err := ctx.Get("rinfo", &rebalInfo) if err != nil { - log.WithField("volume", volinfo.Name).Error("Failed to get rebalinfo") + log.WithError(err).WithField("volume", volInfo.Name).Error("Failed to get rebalance information") return nil, err } // Fill common info - resp.Volname = volinfo.Name - resp.RebalanceID = rebalinfo.RebalanceID + resp.Volname = volInfo.Name + resp.RebalanceID = rebalInfo.RebalanceID + resp.State = rebalInfo.State // Get the status for the completed processes first - for _, tmp := range rebalinfo.RebalStats { + for _, tmp := range rebalInfo.RebalStats { resp.Nodes = append(resp.Nodes, tmp) } // Loop over each node of the volume and aggregate - for _, node := range volinfo.Nodes() { + for _, node := range volInfo.Nodes() { err := ctx.GetNodeResult(node, rebalStatusTxnKey, &tmp) if err != nil { // skip. We might have it in the rebalinfo @@ -325,5 +312,6 @@ func createRebalanceStatusResp(ctx transaction.TxnCtx, volinfo *volume.Volinfo) resp.Nodes = append(resp.Nodes, tmp) } + return &resp, nil }