-
Notifications
You must be signed in to change notification settings - Fork 82
API to remove device #1120
base: master
Are you sure you want to change the base?
API to remove device #1120
Conversation
plugins/device/init.go
Outdated
route.Route{ | ||
Name: "DeviceDelete", | ||
Method: "DELETE", | ||
Pattern: "/devices/{peerid}", |
There was a problem hiding this comment.
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?
plugins/device/rest.go
Outdated
} | ||
defer txn.Done() | ||
|
||
err = deviceutils.DeleteDevice(peerID, deviceName) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
plugins/device/rest.go
Outdated
return | ||
} | ||
|
||
restutils.SendHTTPResponse(ctx, w, http.StatusOK, nil) |
There was a problem hiding this comment.
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
There was a problem hiding this 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.
plugins/device/rest.go
Outdated
} | ||
defer txn.Done() | ||
|
||
err = deviceutils.DeleteDevice(peerID, deviceName) |
There was a problem hiding this comment.
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.
@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 |
TODO list
|
disabling before delete is nice. +1
For now only allow device delete if no LVs in it. |
@rishubhjain Ping! What's pending on this PR? |
plugins/device/rest.go
Outdated
} | ||
defer txn.Done() | ||
|
||
err = deviceutils.DeleteDevice(peerID, deviceName) |
There was a problem hiding this comment.
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
plugins/device/rest.go
Outdated
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, "invalid peer-id passed in url") | ||
return | ||
} | ||
deviceName := r.URL.Query().Get("device") |
There was a problem hiding this comment.
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
plugins/device/init.go
Outdated
route.Route{ | ||
Name: "DeviceDelete", | ||
Method: "DELETE", | ||
Pattern: "/devices/{peerid}", |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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
)
There was a problem hiding this 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
plugins/device/init.go
Outdated
@@ -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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove comment
585b080
to
adc34f2
Compare
There was a problem hiding this 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
e2e/smartvol_ops_test.go
Outdated
|
||
newDeviceList, err := client.DeviceList(tc.gds[0].PeerID()) | ||
|
||
r.NotEqual(len(deviceList), len(newDeviceList)) |
There was a problem hiding this comment.
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))
cafd783
to
91f0e56
Compare
pkg/restclient/device.go
Outdated
} | ||
|
||
// DeviceList lists the devices | ||
func (c *Client) DeviceList(peerid string) ([]deviceapi.Info, error) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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.
2d5a7e7
to
98967b9
Compare
98967b9
to
17496a8
Compare
retest this please |
t.Run("Delete device", testDeviceDelete) | ||
|
||
// // Device Cleanup | ||
r.Nil(loopDevicesCleanup(t)) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
plugins/device/rest.go
Outdated
|
||
err = txn.Do() | ||
if err != nil { | ||
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, "transaction to prepare device failed") |
There was a problem hiding this comment.
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
plugins/device/transaction.go
Outdated
} | ||
|
||
//Remove PV | ||
if err := lvmutils.RemovePV(deviceName); err != nil { |
There was a problem hiding this comment.
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.
plugins/device/transaction.go
Outdated
} | ||
|
||
if vgName == "" { | ||
return errors.New("No device found with given device name") |
There was a problem hiding this comment.
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.
plugins/device/transaction.go
Outdated
} | ||
|
||
if len(devices) == 0 { | ||
return errors.New("No devices added in the given peer") |
There was a problem hiding this comment.
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{ | ||
{ |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
plugins/device/rest.go
Outdated
} | ||
|
||
func listAllDevicesHandler(w http.ResponseWriter, r *http.Request) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this extra line
a6cd208
to
7740aff
Compare
7740aff
to
fb3f69a
Compare
} | ||
|
||
// Remove VG | ||
if err = lvmutils.RemoveVG(vgName); err != nil { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
@rishubhjain please update the commit message with description |
rebase required |
…lete_device Conflicts: e2e/smartvol_ops_test.go
Issue: #1119