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

Edit device #1118

Merged
merged 2 commits into from
Dec 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion doc/endpoints.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

73 changes: 73 additions & 0 deletions e2e/smartvol_ops_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/gluster/glusterd2/pkg/api"
gutils "github.com/gluster/glusterd2/pkg/utils"
deviceapi "github.com/gluster/glusterd2/plugins/device/api"

"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -316,6 +317,77 @@ func testSmartVolumeDistributeDisperse(t *testing.T) {
checkZeroLvs(r)
}

func editDevice(t *testing.T) {
r := require.New(t)
peerList, err := client.Peers()
r.Nil(err)
Copy link
Member

Choose a reason for hiding this comment

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

if peerList len is zero fail the test case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this should be done in the test case of peerList and not in the edit-device.

Copy link
Member

Choose a reason for hiding this comment

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

as this is dependent on the peer list, no harm in having one more higher level check


var deviceList []deviceapi.Info
var peerID string
for _, peer := range peerList {
deviceList, err = client.DeviceList(peer.ID.String())
if len(deviceList) > 0 {
peerID = peer.ID.String()
break
}
}

device := deviceList[0]
if device.State == "enabled" {
err = client.DeviceEdit(peerID, device.Name, "disabled")
r.Nil(err)
} else if device.State == "disabled" {
err = client.DeviceEdit(peerID, device.Name, "enabled")
r.Nil(err)
}
newDeviceList, err := client.DeviceList(peerID)
r.Nil(err)
for _, newDevice := range newDeviceList {
if newDevice.Name == device.Name {
r.NotEqual(newDevice.State, device.State)
}
}

for _, peer := range peerList {
deviceList, err := client.DeviceList(peer.ID.String())
r.Nil(err)
for _, device := range deviceList {
if device.State == "enabled" {
err = client.DeviceEdit(peer.ID.String(), device.Name, "disabled")
r.Nil(err)
}
}
}
smartvolname := formatVolName(t.Name())

// create Distribute Replicate(2x3) Volume
createReq := api.VolCreateReq{
Name: smartvolname,
Size: 40 * gutils.MiB,
DistributeCount: 2,
ReplicaCount: 3,
SubvolZonesOverlap: true,
}
_, err = client.VolumeCreate(createReq)
r.NotNil(err)
Copy link
Member

Choose a reason for hiding this comment

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

enable the devices and create the volume, the volume creation should be successful.


for _, peer := range peerList {
deviceList, err := client.DeviceList(peer.ID.String())
r.Nil(err)
for _, device := range deviceList {
if device.State == "disabled" {
err = client.DeviceEdit(peer.ID.String(), device.Name, "enabled")
r.Nil(err)
}
}
}

_, err = client.VolumeCreate(createReq)
r.Nil(err)

r.Nil(client.VolumeDelete(smartvolname))
}

// TestSmartVolume creates a volume and starts it, runs further tests on it and
// finally deletes the volume
func TestSmartVolume(t *testing.T) {
Expand Down Expand Up @@ -355,6 +427,7 @@ func TestSmartVolume(t *testing.T) {
t.Run("Smartvol Disperse Volume", testSmartVolumeDisperse)
t.Run("Smartvol Distributed-Replicate Volume", testSmartVolumeDistributeReplicate)
t.Run("Smartvol Distributed-Disperse Volume", testSmartVolumeDistributeDisperse)
t.Run("Edit device", editDevice)

// // Device Cleanup
r.Nil(loopDevicesCleanup(t))
Expand Down
25 changes: 23 additions & 2 deletions pkg/restclient/device.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
package restclient

import (
"fmt"
"net/http"
"strings"

deviceapi "github.com/gluster/glusterd2/plugins/device/api"
)

// DeviceAdd registers devices
func (c *Client) DeviceAdd(peerid string, device string) (deviceapi.AddDeviceResp, error) {
// DeviceAdd registers device
func (c *Client) DeviceAdd(peerid, device string) (deviceapi.AddDeviceResp, error) {
var peerinfo deviceapi.AddDeviceResp
req := deviceapi.AddDeviceReq{
Device: device,
}
err := c.post("/v1/devices/"+peerid, req, http.StatusOK, &peerinfo)
return peerinfo, err
}

// DeviceList lists the devices
func (c *Client) DeviceList(peerid string) ([]deviceapi.Info, error) {
var deviceList deviceapi.ListDeviceResp
url := fmt.Sprintf("/v1/devices/%s", peerid)
err := c.get(url, nil, http.StatusOK, &deviceList)
return deviceList, err
}

// DeviceEdit edits device
func (c *Client) DeviceEdit(peerid, device, state string) error {
req := deviceapi.EditDeviceReq{
State: state,
}
device = strings.TrimLeft(device, "/")
url := fmt.Sprintf("/v1/devices/%s/%s", peerid, device)
err := c.post(url, req, http.StatusOK, nil)
return err
}
3 changes: 1 addition & 2 deletions plugins/device/api/req.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@ type AddDeviceReq struct {

// EditDeviceReq structure
type EditDeviceReq struct {
DeviceName string `json:"device-name"`
State string `json:"state"`
State string `json:"state"`
}
7 changes: 5 additions & 2 deletions plugins/device/deviceutils/store-utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,20 @@ func GetDevicesFromPeer(peerInfo *peer.Peer) ([]deviceapi.Info, error) {
}

// SetDeviceState sets device state and updates device state in etcd
func SetDeviceState(peerID, deviceName, deviceState string) error {
func SetDeviceState(peerID, device, deviceState string) error {

devices, err := GetDevices(peerID)
if err != nil {
return err
}

index := DeviceInList(deviceName, devices)
index := DeviceInList(device, devices)
if index < 0 {
return errors.New("device does not exist in the given peer")
}
if devices[index].State == deviceState {
return nil
}
devices[index].State = deviceState
return updateDevices(peerID, devices)
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/device/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (p *Plugin) RestRoutes() route.Routes {
route.Route{
Name: "DeviceEdit",
Method: "POST",
Pattern: "/devices/{peerid}",
Pattern: "/devices/{peerid}/{device:.*}",
Version: 1,
RequestType: utils.GetTypeString((*deviceapi.EditDeviceReq)(nil)),
HandlerFunc: deviceEditHandler},
Expand Down
13 changes: 11 additions & 2 deletions plugins/device/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ func deviceEditHandler(w http.ResponseWriter, r *http.Request) {
return
}

device := mux.Vars(r)["device"]
if device == "" {
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, "device not provided in URL")
return
}

// Adding prefix (/) to device
device = "/" + device

req := new(deviceapi.EditDeviceReq)
if err := restutils.UnmarshalRequest(r, req); err != nil {
logger.WithError(err).Error("Failed to unmarshal request")
Expand All @@ -151,15 +160,15 @@ func deviceEditHandler(w http.ResponseWriter, r *http.Request) {
return
}

txn, err := transaction.NewTxnWithLocks(ctx, peerID)
txn, err := transaction.NewTxnWithLocks(ctx, peerID+device)
if err != nil {
status, err := restutils.ErrToStatusCode(err)
restutils.SendHTTPError(ctx, w, status, err)
return
}
defer txn.Done()

err = deviceutils.SetDeviceState(peerID, req.DeviceName, req.State)
err = deviceutils.SetDeviceState(peerID, device, req.State)
if err != nil {
logger.WithError(err).WithField("peerid", peerID).Error("Failed to update device state in store")
status, err := restutils.ErrToStatusCode(err)
Expand Down