1
0
mirror of https://github.com/gluster/glusterd2.git synced 2026-02-05 21:45:43 +01:00
Files
glusterd2/plugins/device/rest.go
Aravinda VK bebbc65052 Support for loopback bricks
Register the Bricks hosting directory using,

```
glustercli device add <peerid> <path> --provisioner loop
```

Example:

```
glustercli device add 70d79c3f-e7af-43f6-8b65-05dff2423da1 \
	   /exports --provisioner loop
```

Now create the volume using,

```
glustercli volume create gv1 --size 1G \
	   --provisioner loop \
	   --replica 3
```

Fixes: #1418
Signed-off-by: Aravinda VK <avishwan@redhat.com>
2019-02-14 10:49:17 +05:30

202 lines
6.0 KiB
Go

package device
import (
"fmt"
"net/http"
"strings"
"github.com/gluster/glusterd2/glusterd2/gdctx"
"github.com/gluster/glusterd2/glusterd2/peer"
restutils "github.com/gluster/glusterd2/glusterd2/servers/rest/utils"
"github.com/gluster/glusterd2/glusterd2/transaction"
"github.com/gluster/glusterd2/pkg/api"
"github.com/gluster/glusterd2/pkg/errors"
deviceapi "github.com/gluster/glusterd2/plugins/device/api"
"github.com/gluster/glusterd2/plugins/device/deviceutils"
"github.com/gorilla/mux"
"github.com/pborman/uuid"
)
func deviceAddHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := gdctx.GetReqLogger(ctx)
peerID := mux.Vars(r)["peerid"]
if uuid.Parse(peerID) == nil {
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, "invalid peer-id passed in url")
return
}
req := new(deviceapi.AddDeviceReq)
if err := restutils.UnmarshalRequest(r, req); err != nil {
logger.WithError(err).Error("Failed to unmarshal request")
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, errors.ErrJSONParsingFailed)
return
}
if req.ProvisionerType == "" {
req.ProvisionerType = api.ProvisionerTypeLvm
}
txn, err := transaction.NewTxnWithLocks(ctx, peerID)
if err != nil {
status, err := restutils.ErrToStatusCode(err)
restutils.SendHTTPError(ctx, w, status, err)
return
}
defer txn.Done()
_, err = deviceutils.GetDevice(peerID, req.Device)
if err == nil {
logger.WithError(err).WithField("device", req.Device).Error("Device already exists")
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, "device already exists")
return
}
if err != errors.ErrDeviceNotFound {
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err)
return
}
peerInfo, err := peer.GetPeer(peerID)
if err != nil {
logger.WithError(err).WithField("peerid", peerID).Error("Peer ID not found in store")
if err == errors.ErrPeerNotFound {
restutils.SendHTTPError(ctx, w, http.StatusNotFound, errors.ErrPeerNotFound)
} else {
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, "failed to get peer details from store")
}
return
}
txn.Nodes = []uuid.UUID{peerInfo.ID}
txn.Steps = []*transaction.Step{
{
DoFunc: "prepare-device",
Nodes: txn.Nodes,
},
}
err = txn.Ctx.Set("peerid", &peerID)
if err != nil {
logger.WithError(err).WithField("key", "peerid").WithField("value", peerID).Error("Failed to set key in transaction context")
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err)
return
}
err = txn.Ctx.Set("req", &req)
if err != nil {
logger.WithError(err).WithField("key", "req").Error("Failed to set key in transaction context")
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err)
return
}
err = txn.Do()
if err != nil {
logger.WithError(err).Error("Transaction to prepare device failed")
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, "transaction to prepare device failed")
return
}
deviceInfo, err := deviceutils.GetDevice(peerID, req.Device)
if err != nil {
logger.WithError(err).WithField("peerid", peerID).Error("Failed to get device from store")
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, "failed to get device from store")
return
}
restutils.SetLocationHeader(r, w, strings.TrimLeft(deviceInfo.Device, "/"))
restutils.SendHTTPResponse(ctx, w, http.StatusCreated, deviceInfo)
}
func deviceListHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := gdctx.GetReqLogger(ctx)
peerID := mux.Vars(r)["peerid"]
if peerID != "" && uuid.Parse(peerID) == nil {
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, "invalid peer-id passed in url")
return
}
devName := mux.Vars(r)["device"]
devName = "/" + devName
var err error
var devices []deviceapi.Info
if peerID == "" {
devices, err = deviceutils.GetDevices()
} else {
if devName != "/" {
var dev *deviceapi.Info
dev, err = deviceutils.GetDevice(peerID, devName)
if err == nil {
devices = []deviceapi.Info{*dev}
}
} else {
devices, err = deviceutils.GetDevices(peerID)
}
}
if err != nil {
logger.WithError(err).WithField("peerid", peerID).Error(
"Failed to get devices for peer")
status, err := restutils.ErrToStatusCode(err)
restutils.SendHTTPError(ctx, w, status, err)
return
}
restutils.SendHTTPResponse(ctx, w, http.StatusOK, devices)
}
func deviceEditHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := gdctx.GetReqLogger(ctx)
peerID := mux.Vars(r)["peerid"]
if uuid.Parse(peerID) == nil {
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, "invalid peer-id passed in url")
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")
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, errors.ErrJSONParsingFailed)
return
}
if req.State != deviceapi.DeviceEnabled && req.State != deviceapi.DeviceDisabled {
logger.WithField("device-state", req.State).Error("State provided in request does not match any supported state")
errMsg := fmt.Sprintf("invalid state. Supported states are %s, %s", deviceapi.DeviceEnabled, deviceapi.DeviceDisabled)
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, errMsg)
return
}
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, 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)
restutils.SendHTTPError(ctx, w, status, err)
return
}
restutils.SendHTTPResponse(ctx, w, http.StatusOK, nil)
}