From 3f8a2f20806a6acbeaa2d2121ce92c312ad30ed0 Mon Sep 17 00:00:00 2001 From: rishubhjain Date: Tue, 18 Dec 2018 05:52:24 -0500 Subject: [PATCH] Check whether peer has devices before removing peer Signedoff-by: rishubhjain --- e2e/peer_ops_test.go | 16 +++++++++++++++- glusterd2/commands/peers/deletepeer.go | 22 ++++++++++++++++++++++ pkg/restclient/device.go | 8 ++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/e2e/peer_ops_test.go b/e2e/peer_ops_test.go index 29e3abcc9..57509f3c8 100644 --- a/e2e/peer_ops_test.go +++ b/e2e/peer_ops_test.go @@ -95,7 +95,21 @@ func TestAddRemovePeer(t *testing.T) { r.Len(peers, 0) } - // remove peer: ask g1 to remove g2 as peer + devicesDir := testTempDir(t, "devices") + r.Nil(prepareLoopDevice(devicesDir+"/gluster_dev1.img", "1", "250M")) + _, err = client.DeviceAdd(g2.PeerID(), "/dev/gluster_loop1") + r.Nil(err) + + dev, err := client.DeviceList(g2.PeerID(), "/dev/gluster_loop1") + r.Nil(err) + r.Equal(dev[0].Device, "/dev/gluster_loop1") + err = client.PeerRemove(g2.PeerID()) + r.NotNil(err) + + err = client.PeerRemove(g3.PeerID()) r.Nil(err) + + // Device Cleanup + r.Nil(loopDevicesCleanup(t)) } diff --git a/glusterd2/commands/peers/deletepeer.go b/glusterd2/commands/peers/deletepeer.go index 7f1aa55d6..eb2594926 100644 --- a/glusterd2/commands/peers/deletepeer.go +++ b/glusterd2/commands/peers/deletepeer.go @@ -11,6 +11,7 @@ import ( "github.com/gluster/glusterd2/glusterd2/store" "github.com/gluster/glusterd2/glusterd2/volume" "github.com/gluster/glusterd2/pkg/utils" + "github.com/gluster/glusterd2/plugins/device/deviceutils" "github.com/gorilla/mux" "github.com/pborman/uuid" @@ -70,6 +71,16 @@ func deletePeerHandler(w http.ResponseWriter, r *http.Request) { return } + if exists, err := deviceExist(id); err != nil { + logger.WithError(err).Error("failed to check if device exist on peer") + restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, "could not validate delete peer request") + return + } else if exists { + logger.Debug("request denied, peer has devices") + restutils.SendHTTPError(ctx, w, http.StatusForbidden, "cannot delete peer, peer has device/devices") + return + } + remotePeerAddress, err := utils.FormRemotePeerAddress(p.PeerAddresses[0]) if err != nil { logger.WithError(err).WithField("address", p.PeerAddresses[0]).Error("failed to parse peer address") @@ -119,6 +130,17 @@ func deletePeerHandler(w http.ResponseWriter, r *http.Request) { events.Broadcast(newPeerEvent(eventPeerRemoved, p)) } +func deviceExist(id string) (bool, error) { + deviceInfo, err := deviceutils.GetDevices(id) + if err != nil { + return false, err + } + if len(deviceInfo) > 0 { + return true, nil + } + return false, nil +} + // bricksExist checks if the given peer has any bricks on it // TODO: Move this to a more appropriate place func bricksExist(id string) (bool, error) { diff --git a/pkg/restclient/device.go b/pkg/restclient/device.go index c2e8a4173..cb4793d67 100644 --- a/pkg/restclient/device.go +++ b/pkg/restclient/device.go @@ -43,3 +43,11 @@ func (c *Client) DeviceEdit(peerid, device, state string) error { err := c.post(url, req, http.StatusOK, nil) return err } + +// DevicesInPeer lists devices in peer +func (c *Client) DevicesInPeer(peerid string) (deviceapi.ListDeviceResp, error) { + var deviceList deviceapi.ListDeviceResp + url := fmt.Sprintf("/v1/devices/%s", peerid) + err := c.get(url, nil, http.StatusOK, &deviceList) + return deviceList, err +}