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

Commit

Permalink
Merge pull request #532 from rishubhjain/deviceadd
Browse files Browse the repository at this point in the history
Adding Device
  • Loading branch information
prashanthpai authored Feb 27, 2018
2 parents d7f0112 + ab22917 commit b5f8705
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 0 deletions.
2 changes: 2 additions & 0 deletions glusterd2/plugin/plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package plugin

import (
"github.com/gluster/glusterd2/plugins/bitrot"
"github.com/gluster/glusterd2/plugins/device"
"github.com/gluster/glusterd2/plugins/events"
"github.com/gluster/glusterd2/plugins/georeplication"
"github.com/gluster/glusterd2/plugins/glustershd"
Expand All @@ -17,4 +18,5 @@ var PluginsList = []GlusterdPlugin{
&quota.Plugin{},
&events.Plugin{},
&glustershd.Plugin{},
&device.Plugin{},
}
17 changes: 17 additions & 0 deletions plugins/device/api/req.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package device

const (
// DeviceEnabled represents enabled
DeviceEnabled = "Enabled"

// DeviceDisabled represents disabled
DeviceDisabled = "Disabled"

// DeviceFailed represents failed
DeviceFailed = "Failed"
)

// AddDeviceReq structure
type AddDeviceReq struct {
Devices []string `json:"devices"`
}
14 changes: 14 additions & 0 deletions plugins/device/api/resp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package device

import (
"github.com/gluster/glusterd2/pkg/api"
)

// Info represents structure in which devices are to be store in Peer MetaData
type Info struct {
Name string `json:"name"`
State string `json:"state"`
}

// AddDeviceResp is the success response sent to a AddDeviceReq request
type AddDeviceResp api.Peer
43 changes: 43 additions & 0 deletions plugins/device/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package device

import (
"github.com/gluster/glusterd2/glusterd2/servers/rest/route"
"github.com/gluster/glusterd2/glusterd2/transaction"
"github.com/gluster/glusterd2/pkg/sunrpc"
"github.com/gluster/glusterd2/pkg/utils"
deviceapi "github.com/gluster/glusterd2/plugins/device/api"
)

// Plugin is a structure which implements GlusterdPlugin interface
type Plugin struct {
}

// Name returns name of plugin
func (p *Plugin) Name() string {
return "device"
}

// SunRPCProgram returns sunrpc program to register with Glusterd
func (p *Plugin) SunRPCProgram() sunrpc.Program {
return nil
}

// RestRoutes returns list of REST API routes to register with Glusterd.
func (p *Plugin) RestRoutes() route.Routes {
return route.Routes{
route.Route{
Name: "DeviceAdd",
Method: "POST",
Pattern: "/peers/{peerid}/devices",
Version: 1,
RequestType: utils.GetTypeString((*deviceapi.AddDeviceReq)(nil)),
ResponseType: utils.GetTypeString((*deviceapi.AddDeviceResp)(nil)),
HandlerFunc: deviceAddHandler},
}
}

// RegisterStepFuncs registers transaction step functions with
// Glusterd Transaction framework
func (p *Plugin) RegisterStepFuncs() {
transaction.RegisterStepFunc(txnPrepareDevice, "prepare-device")
}
76 changes: 76 additions & 0 deletions plugins/device/rest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package device

import (
"net/http"

"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"
deviceapi "github.com/gluster/glusterd2/plugins/device/api"

"github.com/gorilla/mux"
"github.com/pborman/uuid"
)

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

ctx := r.Context()
logger := gdctx.GetReqLogger(ctx)

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, "Unable to marshal request", api.ErrCodeDefault)
return
}
peerID := mux.Vars(r)["peerid"]
if peerID == "" {
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, "peerid not present in request", api.ErrCodeDefault)
return
}
peerInfo, err := peer.GetPeer(peerID)
if err != nil {
logger.WithError(err).WithField("peerid", peerID).Error("Peer ID not found in store")
restutils.SendHTTPError(ctx, w, http.StatusNotFound, "Peer Id not found in store", api.ErrCodeDefault)
return
}
txn := transaction.NewTxn(ctx)
defer txn.Cleanup()
lock, unlock, err := transaction.CreateLockSteps(peerInfo.ID.String())
txn.Nodes = []uuid.UUID{peerInfo.ID}
txn.Steps = []*transaction.Step{
lock,
{
DoFunc: "prepare-device",
Nodes: txn.Nodes,
},
unlock,
}
err = txn.Ctx.Set("peerid", peerID)
if err != nil {
logger.WithError(err).Error("Failed to set data for transaction")
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err.Error(), api.ErrCodeDefault)
return
}
err = txn.Ctx.Set("req", req)
if err != nil {
logger.WithError(err).Error("Failed to set data for transaction")
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err.Error(), api.ErrCodeDefault)
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", api.ErrCodeDefault)
return
}
peerInfo, err = peer.GetPeer(peerID)
if err != nil {
logger.WithError(err).Error("Failed to get peer from store")
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, "Failed to get peer from store", api.ErrCodeDefault)
return
}
restutils.SendHTTPResponse(ctx, w, http.StatusOK, peerInfo)
}
51 changes: 51 additions & 0 deletions plugins/device/store-utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package device

import (
"encoding/json"

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

// GetDevices returns devices of specified peer from the store
func GetDevices(peerID string) ([]deviceapi.Info, error) {
peerInfo, err := peer.GetPeer(peerID)
if err != nil {
return nil, err
}
if len(peerInfo.MetaData["devices"]) > 0 {
var deviceInfo []deviceapi.Info
if err := json.Unmarshal([]byte(peerInfo.MetaData["devices"]), &deviceInfo); err != nil {
return nil, err
}
return deviceInfo, nil
}
return nil, nil
}

// AddDevices adds device to specific peer
func AddDevices(devices []deviceapi.Info, peerID string) error {
deviceDetails, err := GetDevices(peerID)
if err != nil {
return err
}
peerInfo, err := peer.GetPeer(peerID)
if err != nil {
return err
}
if deviceDetails != nil {
devices = append(devices, deviceDetails...)
}
deviceJSON, err := json.Marshal(devices)
if err != nil {
return err
}
peerInfo.MetaData["devices"] = string(deviceJSON)
err = peer.AddOrUpdatePeer(peerInfo)
if err != nil {
return err
}

return nil

}
53 changes: 53 additions & 0 deletions plugins/device/transaction.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package device

import (
"os/exec"
"strings"

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

"github.com/pborman/uuid"
log "github.com/sirupsen/logrus"
)

func txnPrepareDevice(c transaction.TxnCtx) error {
var peerID uuid.UUID
var req deviceapi.AddDeviceReq
var deviceList []deviceapi.Info
if err := c.Get("peerid", peerID); err != nil {
c.Logger().WithError(err).Error("Failed transaction, cannot find peer-id")
return err
}
if err := c.Get("req", req); err != nil {
c.Logger().WithError(err).Error("Failed transaction, cannot find device-details")
return err
}
for _, name := range req.Devices {
tempDevice := deviceapi.Info{
Name: name,
}
deviceList = append(deviceList, tempDevice)
}
for index, element := range deviceList {
pvcreateCmd := exec.Command("pvcreate", "--metadatasize=128M", "--dataalignment=256K", element.Name)
if err := pvcreateCmd.Run(); err != nil {
c.Logger().WithError(err).WithField("device", element.Name).Error("pvcreate failed for device")
deviceList[index].State = deviceapi.DeviceFailed
continue
}
vgcreateCmd := exec.Command("vgcreate", strings.Replace("vg"+element.Name, "/", "-", -1), element.Name)
if err := vgcreateCmd.Run(); err != nil {
c.Logger().WithError(err).WithField("device", element.Name).Error("vgcreate failed for device")
deviceList[index].State = deviceapi.DeviceFailed
continue
}
deviceList[index].State = deviceapi.DeviceEnabled
}
err := AddDevices(deviceList, peerID.String())
if err != nil {
log.WithError(err).Error("Couldn't add deviceinfo to store")
return err
}
return nil
}

0 comments on commit b5f8705

Please sign in to comment.