Skip to content
This repository has been archived by the owner on Mar 26, 2020. It is now read-only.

API to remove device #1120

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

Conversation

rishubhjain
Copy link
Contributor

Issue: #1119

route.Route{
Name: "DeviceDelete",
Method: "DELETE",
Pattern: "/devices/{peerid}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a comment saying the device ID is a query param?

}
defer txn.Done()

err = deviceutils.DeleteDevice(peerID, deviceName)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: don't we need to lock device before deleting it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#998, as @aravindavk said we need to lock device for smart volume creation, the same way we should consider locking device before deleting it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use lock as PeerID + deviceName

return
}

restutils.SendHTTPResponse(ctx, w, http.StatusOK, nil)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the response should be 204 for a delete operation

Copy link
Member

@Madhu-1 Madhu-1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of adding review comments by mistake I have added it as just comments.

}
defer txn.Done()

err = deviceutils.DeleteDevice(peerID, deviceName)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#998, as @aravindavk said we need to lock device for smart volume creation, the same way we should consider locking device before deleting it.

@Madhu-1
Copy link
Member

Madhu-1 commented Aug 7, 2018

@rishubhjain I would suggest disabling the device first so it won't be considered for any volume/brick creation, later we can delete the device. just a question, how are we planning to move bricks from the device to another device before deleting it?

@aravindavk @phlogistonjohn @raghavendra-talur @obnoxxx need input from your side on this

@Madhu-1
Copy link
Member

Madhu-1 commented Aug 7, 2018

TODO list

  • CLI
  • rest API
  • e2e test cases
  • endpoint update

@aravindavk
Copy link
Member

@rishubhjain I would suggest disabling the device first so it won't be considered for any volume/brick creation, later we can delete the device. just a question, how are we planning to move bricks from the device to another device before deleting it?

disabling before delete is nice. +1

just a question, how are we planning to move bricks from the device to another device before deleting it?

For now only allow device delete if no LVs in it.

@atinmu
Copy link
Contributor

atinmu commented Nov 10, 2018

@rishubhjain Ping! What's pending on this PR?

}
defer txn.Done()

err = deviceutils.DeleteDevice(peerID, deviceName)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use lock as PeerID + deviceName

restutils.SendHTTPError(ctx, w, http.StatusBadRequest, "invalid peer-id passed in url")
return
}
deviceName := r.URL.Query().Get("device")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use query use in url itself

route.Route{
Name: "DeviceDelete",
Method: "DELETE",
Pattern: "/devices/{peerid}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/devices/{peerid}/{device:.*}

return errors.New("device does not exist in the given peer")
}

if devices[index].Used {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this flag is updated on volume delete. Please open new issue to rename this field to NumberOfBricks.

Remove this check from here(add TODO note). While addressing the new issue, check need to be added again(if devices[index].NumberOfBricks == 0)

@ghost ghost assigned rishubhjain Nov 29, 2018
@ghost ghost added the in progress label Nov 29, 2018
Copy link
Member

@aravindavk aravindavk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a restclient function and tests

@@ -48,6 +48,15 @@ func (p *Plugin) RestRoutes() route.Routes {
Version: 1,
ResponseType: utils.GetTypeString((*deviceapi.ListDeviceResp)(nil)),
HandlerFunc: listAllDevicesHandler},
// device name is passed as query param in url.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove comment

Copy link
Member

@aravindavk aravindavk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. one minor comment about the test


newDeviceList, err := client.DeviceList(tc.gds[0].PeerID())

r.NotEqual(len(deviceList), len(newDeviceList))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check using Equal. r.Equal(len(deviceList) - 1, len(newDeviceList))

@rishubhjain rishubhjain force-pushed the delete_device branch 7 times, most recently from cafd783 to 91f0e56 Compare December 1, 2018 10:31
}

// DeviceList lists the devices
func (c *Client) DeviceList(peerid string) ([]deviceapi.Info, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is repeated in PR #1118

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I required this for the e2e test cases, will rebase once that PR is merged.

@@ -170,6 +170,42 @@ func deviceEditHandler(w http.ResponseWriter, r *http.Request) {
restutils.SendHTTPResponse(ctx, w, http.StatusOK, nil)
}

func deviceDeleteHandler(w http.ResponseWriter, r *http.Request) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, I missed it earlier. We need to remove the device using vgremove and pvremove as a transaction step. Deleting device from etcd should be last step.

@rishubhjain rishubhjain force-pushed the delete_device branch 3 times, most recently from 2d5a7e7 to 98967b9 Compare December 11, 2018 11:07
@rishubhjain
Copy link
Contributor Author

retest this please

t.Run("Delete device", testDeviceDelete)

// // Device Cleanup
r.Nil(loopDevicesCleanup(t))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this after device add? even if the device remove or device list fails, these block fo code won't get hit. it's good to do cleanup in defer().
@aravindavk let me know your thoughts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move all the clean up task to defer? Like deleting and stopping volume etc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is also called in main_test.go, so should be fine


err = txn.Do()
if err != nil {
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, "transaction to prepare device failed")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even the device is not present in the peer is considered as internal server error, need to handle not found error also

}

//Remove PV
if err := lvmutils.RemovePV(deviceName); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make use of err throughout the function. don't create a new variable for each block.

}

if vgName == "" {
return errors.New("No device found with given device name")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an error message should start with the small case. and move this error message to error pkg. it will be helpful for the consumer.

}

if len(devices) == 0 {
return errors.New("No devices added in the given peer")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here as well


txn.Nodes = []uuid.UUID{peerInfo.ID}
txn.Steps = []*transaction.Step{
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aravindavk don't we need to check any volume present on the device before removing it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vgremove will fail if the device is being used. We don't wipe the device

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no harm in checking any volume present on the device, so that user will get a meaning full message something like bricks present on the device, cannot delete the device,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

func listAllDevicesHandler(w http.ResponseWriter, r *http.Request) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this extra line

}

// Remove VG
if err = lvmutils.RemoveVG(vgName); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens when the VG is already deleted in the last execution and something failed in PV deletion below?
before deleting the resource don't we need to check if the resource is available or not?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Madhu-1 Can you elaborate more on whether resource is available or not. Do you mean whether the device exist or in use or not?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rishubhjain during the device removal if the VG removal was successful and it got failed in PV remove stage, and if the user again tries to delete the device, it will fail with VG not found error right, how are we solving this problem?
dont we need to handle VG not found scenario and PV not found scenario?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aravindavk Can you help me with this? the basic way would be to check pvs and vgs before removing to avoid issues. But it's not a clean solution, can you suggest a cleaner solution to handle this scenerio?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try to delete VG and continue if it is not exists error. But if Vg is not found make sure no Vg exists before removing PV.(If user manually deleted Vg and Created Vg with different name then gd2 may end up deleting, If PV fails when Vg exists then that is also Ok)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also check PV not exists. If Pv not exists then remove only from store and return success

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only possible if user manually deletes PV right?

@Madhu-1
Copy link
Member

Madhu-1 commented Dec 13, 2018

@rishubhjain please update the commit message with description

@aravindavk
Copy link
Member

rebase required

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants