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

Commit

Permalink
block volume: added a common function for updating available hosting …
Browse files Browse the repository at this point in the history
…volume size

 - moved hosts parameter from mandatory to optional field in  CreateBlockVolume
   method of BlockProvider interface,since hosts field may not required for
   other block providers like loopback.

 - a common function for updating available hosting volume size will prevent
   from duplicate code

Signed-off-by: Oshank Kumar <[email protected]>
  • Loading branch information
Oshank Kumar committed Jan 3, 2019
1 parent e34b34a commit 56f9240
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 64 deletions.
4 changes: 4 additions & 0 deletions doc/endpoints.md

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

20 changes: 10 additions & 10 deletions pkg/size/size.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,24 +134,24 @@ func (s Size) TebiBytes() float64 {
return float64(tib) + float64(bytes)/(1024*1024*1024*1024)
}

// String string representation of Size in form XXKB/MB/TB/GB/Bytes
// TODO: support for string representation in XiB format
// String string representation of Size in form XXKiB/MiB/TiB/GiB/B
// TODO: support for string representation in other formats
func (s Size) String() string {

if s >= TB {
return fmt.Sprintf("%.2fTB", s.TeraBytes())
if s >= TiB {
return fmt.Sprintf("%.2fTiB", s.TebiBytes())
}

if s >= GB {
return fmt.Sprintf("%.2fGB", s.GigaBytes())
if s >= GiB {
return fmt.Sprintf("%.2fGiB", s.GibiBytes())
}

if s >= MB {
return fmt.Sprintf("%.2fMB", s.MegaBytes())
if s >= MiB {
return fmt.Sprintf("%.2fMiB", s.MebiBytes())
}

if s >= KB {
return fmt.Sprintf("%.2fKB", s.KiloBytes())
if s >= KiB {
return fmt.Sprintf("%.2fKiB", s.KibiBytes())
}

return fmt.Sprintf("%d B", s)
Expand Down
8 changes: 4 additions & 4 deletions pkg/size/size_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ var (
s Size
want string
}{
{Size(1e12), "1.00TB"},
{Size(2.5e9), "2.50GB"},
{Size(8.75e6), "8.75MB"},
{Size(768e3), "768.00KB"},
{Size(1099511627776), "1.00TiB"},
{Size(2684354560), "2.50GiB"},
{Size(9175040), "8.75MiB"},
{Size(786432), "768.00KiB"},
{Size(500), "500 B"},
}

Expand Down
2 changes: 1 addition & 1 deletion plugins/blockvolume/blockprovider/blockvolume_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var (

// Provider is an abstract, pluggable interface for block volume providers
type Provider interface {
CreateBlockVolume(name string, size uint64, hosts []string, hostVolume string, options ...BlockVolOption) (BlockVolume, error)
CreateBlockVolume(name string, size uint64, hostVolume string, options ...BlockVolOption) (BlockVolume, error)
DeleteBlockVolume(name string, options ...BlockVolOption) error
GetBlockVolume(id string) (BlockVolume, error)
BlockVolumes() []BlockVolume
Expand Down
55 changes: 18 additions & 37 deletions plugins/blockvolume/blockprovider/gluster-block/glusterblock.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@ package glusterblock
import (
"context"
"errors"
"fmt"
"strconv"

"github.com/gluster/glusterd2/glusterd2/transaction"
"github.com/gluster/glusterd2/glusterd2/volume"
"github.com/gluster/glusterd2/pkg/size"
"github.com/gluster/glusterd2/plugins/blockvolume/blockprovider"
"github.com/gluster/glusterd2/plugins/blockvolume/utils"
"time"

"github.com/gluster/gluster-block-restapi/client"
"github.com/gluster/gluster-block-restapi/pkg/api"
Expand Down Expand Up @@ -44,6 +41,7 @@ func newGlusterBlock() (blockprovider.Provider, error) {
opts = append(opts,
client.WithAuth(clientConf.User, clientConf.Secret),
client.WithTLSConfig(&client.TLSOptions{CaCertFile: clientConf.CaCertFile, InsecureSkipVerify: clientConf.Insecure}),
client.WithTimeOut(time.Minute),
)

gbClient, err := client.NewClientWithOpts(clientConf.HostAddress, opts...)
Expand All @@ -56,13 +54,14 @@ func newGlusterBlock() (blockprovider.Provider, error) {
}

// CreateBlockVolume will create a gluster block volume with given name and size having `hostVolume` as hosting volume
func (g *GlusterBlock) CreateBlockVolume(name string, size uint64, hosts []string, hostVolume string, options ...blockprovider.BlockVolOption) (blockprovider.BlockVolume, error) {
var (
blockVolOpts = &blockprovider.BlockVolumeOptions{}
clusterLocks = transaction.Locks{}
)

func (g *GlusterBlock) CreateBlockVolume(name string, size uint64, hostVolume string, options ...blockprovider.BlockVolOption) (blockprovider.BlockVolume, error) {
blockVolOpts := &blockprovider.BlockVolumeOptions{}
blockVolOpts.ApplyOpts(options...)
logger := log.WithFields(log.Fields{
"block_name": name,
"hostvol": hostVolume,
"requested_block_size": size,
})

req := &api.BlockVolumeCreateReq{
HaCount: blockVolOpts.Ha,
Expand All @@ -71,42 +70,22 @@ func (g *GlusterBlock) CreateBlockVolume(name string, size uint64, hosts []strin
Size: size,
Storage: blockVolOpts.Storage,
RingBufferSizeInMB: blockVolOpts.RingBufferSizeInMB,
Hosts: hosts,
}

if err := clusterLocks.Lock(hostVolume); err != nil {
log.WithError(err).Error("error in acquiring cluster lock")
return nil, err
}
defer clusterLocks.UnLock(context.Background())

volInfo, err := volume.GetVolume(hostVolume)
if err != nil {
return nil, fmt.Errorf("error in getting host vol details: %s", err)
}

availableSizeInBytes, err := strconv.ParseUint(volInfo.Metadata[volume.BlockHostingAvailableSize], 10, 64)
if err != nil {
return nil, err
}

if availableSizeInBytes < size {
return nil, fmt.Errorf("available size is less than requested size,request size: %d, available size: %d", size, availableSizeInBytes)
Hosts: blockVolOpts.Hosts,
}

resp, err := g.client.CreateBlockVolume(hostVolume, name, req)
if err != nil {
logger.WithError(err).Error("failed in creating gluster block volume")
return nil, err
}

volInfo.Metadata[volume.BlockHostingAvailableSize] = fmt.Sprintf("%d", availableSizeInBytes-size)

if err = volume.AddOrUpdateVolume(volInfo); err != nil {
log.WithError(err).Error("failed in updating volume info to store")
resizeFunc := func(blockHostingAvailableSize, blockSize uint64) uint64 { return blockHostingAvailableSize - blockSize }
if err = utils.ResizeBlockHostingVolume(hostVolume, size, resizeFunc); err != nil {
logger.WithError(err).Error("failed in updating hostvolume _block-hosting-available-size metadata")
}

return &BlockVolume{
hostVolume: volInfo.Name,
hostVolume: hostVolume,
name: name,
hosts: resp.Portals,
iqn: resp.IQN,
Expand Down Expand Up @@ -153,7 +132,9 @@ func (g *GlusterBlock) DeleteBlockVolume(name string, options ...blockprovider.B
return err
}

if err = utils.ResizeBlockHostingVolume(hostVol, blockInfo.Size); err != nil {
resizeFunc := func(blockHostingAvailableSize, blockSize uint64) uint64 { return blockHostingAvailableSize + blockSize }

if err = utils.ResizeBlockHostingVolume(hostVol, blockInfo.Size, resizeFunc); err != nil {
log.WithFields(log.Fields{
"error": err,
"size": blockInfo.Size,
Expand Down
8 changes: 8 additions & 0 deletions plugins/blockvolume/blockprovider/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type BlockVolumeOptions struct {
RingBufferSizeInMB uint64
ForceDelete bool
UnlinkStorage bool
Hosts []string
}

// ApplyOpts applies configured optional parameters on BlockVolumeOptions
Expand Down Expand Up @@ -61,3 +62,10 @@ func WithAuthEnabled(options *BlockVolumeOptions) {
func WithFullPrealloc(options *BlockVolumeOptions) {
options.FullPrealloc = true
}

// WithHosts configures required hosts for block creation
func WithHosts(hosts []string) BlockVolOption {
return func(options *BlockVolumeOptions) {
options.Hosts = hosts
}
}
7 changes: 5 additions & 2 deletions plugins/blockvolume/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ func (b *BlockVolume) CreateVolume(w http.ResponseWriter, r *http.Request) {
return
}

opts = append(opts, blockprovider.WithHaCount(req.HaCount))
opts = append(opts,
blockprovider.WithHaCount(req.HaCount),
blockprovider.WithHosts(req.Clusters),
)

if req.Auth {
opts = append(opts, blockprovider.WithAuthEnabled)
Expand All @@ -42,7 +45,7 @@ func (b *BlockVolume) CreateVolume(w http.ResponseWriter, r *http.Request) {
return
}

blockVol, err := blockProvider.CreateBlockVolume(req.Name, req.Size, req.Clusters, hostVolInfo.Name, opts...)
blockVol, err := blockProvider.CreateBlockVolume(req.Name, req.Size, hostVolInfo.Name, opts...)
if err != nil {
utils.SendHTTPError(r.Context(), w, http.StatusInternalServerError, err)
return
Expand Down
39 changes: 29 additions & 10 deletions plugins/blockvolume/utils/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,25 +80,39 @@ func CreateAndStartHostingVolume(req *api.VolCreateReq) (*volume.Volinfo, error)
return vInfo, nil
}

// ResizeBlockHostingVolume will adds deletedBlockSize to block-hosting-available-size
// in metadata and update the new vol info to store.
func ResizeBlockHostingVolume(volname string, deletedBlockSize string) error {
clusterLocks := transaction.Locks{}
// ResizeBlockHostingVolume will resize the _block-hosting-available-size metadata and update the new vol info to store.
// resizeFunc is use to update the new new value to the _block-hosting-available-size metadata
// e.g for adding the value to the _block-hosting-available-size metadata we can use `resizeFunc` as
// f := func(a, b uint64) uint64{return a +b }
func ResizeBlockHostingVolume(volName string, blockSize interface{}, resizeFunc func(blockHostingAvailableSize, blockSize uint64) uint64) error {
var (
blkSize size.Size
clusterLocks = transaction.Locks{}
)

if err := clusterLocks.Lock(volname); err != nil {
if err := clusterLocks.Lock(volName); err != nil {
log.WithError(err).Error("error in acquiring cluster lock")
return err
}
defer clusterLocks.UnLock(context.Background())

volInfo, err := volume.GetVolume(volname)
volInfo, err := volume.GetVolume(volName)
if err != nil {
return err
}

deletedSize, err := size.Parse(deletedBlockSize)
if err != nil {
return err
switch sz := blockSize.(type) {
case string:
blkSize, err = size.Parse(sz)
if err != nil {
return err
}
case uint64:
blkSize = size.Size(sz)
case int64:
blkSize = size.Size(sz)
default:
return fmt.Errorf("blocksize is not a supported type(%T)", blockSize)
}

if _, found := volInfo.Metadata[volume.BlockHostingAvailableSize]; !found {
Expand All @@ -110,7 +124,12 @@ func ResizeBlockHostingVolume(volname string, deletedBlockSize string) error {
return err
}

volInfo.Metadata[volume.BlockHostingAvailableSize] = fmt.Sprintf("%d", availableSizeInBytes+uint64(deletedSize))
log.WithFields(log.Fields{
"blockHostingAvailableSize": size.Size(availableSizeInBytes),
"blockSize": blkSize,
}).Debug("resizing hosting volume")

volInfo.Metadata[volume.BlockHostingAvailableSize] = fmt.Sprintf("%d", resizeFunc(availableSizeInBytes, uint64(blkSize)))

return volume.AddOrUpdateVolume(volInfo)
}
Expand Down

0 comments on commit 56f9240

Please sign in to comment.