This repository was archived by the owner on Mar 26, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 82
gd2 plugin: added a plugin for block volume management #1357
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
fe42d9e
gd2 plugin: added a plugin for block volume management
4dabeb1
block-volume: moved common code to a utils package
9391a6c
block-volume: added a interface for host volume management.
ffadf9e
block-volume: change size type from int64 to uint64
c60180a
update dependencies using dep ensure
827f2f0
block volume: Fix Merge conflicts in volume-start.go
0561c0e
block volume: added a common function for updating available hosting …
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| package volumecommands | ||
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
| "net/http" | ||
| "path/filepath" | ||
|
|
@@ -102,9 +103,6 @@ func registerVolCreateStepFuncs() { | |
| func volumeCreateHandler(w http.ResponseWriter, r *http.Request) { | ||
|
|
||
| ctx := r.Context() | ||
| ctx, span := trace.StartSpan(ctx, "/volumeCreateHandler") | ||
| defer span.End() | ||
|
|
||
| logger := gdctx.GetReqLogger(ctx) | ||
| var err error | ||
|
|
||
|
|
@@ -114,45 +112,68 @@ func volumeCreateHandler(w http.ResponseWriter, r *http.Request) { | |
| return | ||
| } | ||
|
|
||
| if err := validateVolCreateReq(&req); err != nil { | ||
| restutils.SendHTTPError(ctx, w, http.StatusBadRequest, err) | ||
| if status, err := CreateVolume(ctx, req); err != nil { | ||
| restutils.SendHTTPError(ctx, w, status, err) | ||
| return | ||
| } | ||
|
|
||
| if containsReservedGroupProfile(req.Options) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this check also lost
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
| restutils.SendHTTPError(ctx, w, http.StatusBadRequest, gderrors.ErrReservedGroupProfile) | ||
| volinfo, err := volume.GetVolume(req.Name) | ||
| if err != nil { | ||
| // FIXME: If volume was created successfully in the txn above and | ||
| // then the store goes down by the time we reach here, what do | ||
| // we return to the client ? | ||
| restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) | ||
| return | ||
| } | ||
|
|
||
| logger.WithField("volume-name", volinfo.Name).Info("new volume created") | ||
| events.Broadcast(volume.NewEvent(volume.EventVolumeCreated, volinfo)) | ||
|
|
||
| resp := createVolumeCreateResp(volinfo) | ||
| restutils.SetLocationHeader(r, w, volinfo.Name) | ||
| restutils.SendHTTPResponse(ctx, w, http.StatusCreated, resp) | ||
| } | ||
|
|
||
| func createVolumeCreateResp(v *volume.Volinfo) *api.VolumeCreateResp { | ||
| return (*api.VolumeCreateResp)(volume.CreateVolumeInfoResp(v)) | ||
| } | ||
|
|
||
| // CreateVolume creates a volume | ||
| func CreateVolume(ctx context.Context, req api.VolCreateReq) (status int, err error) { | ||
| ctx, span := trace.StartSpan(ctx, "/volumeCreateHandler") | ||
| defer span.End() | ||
|
|
||
| if err := validateVolCreateReq(&req); err != nil { | ||
| return http.StatusBadRequest, err | ||
| } | ||
|
|
||
| if containsReservedGroupProfile(req.Options) { | ||
| return http.StatusBadRequest, gderrors.ErrReservedGroupProfile | ||
| } | ||
|
|
||
| if req.Size > 0 { | ||
| applyDefaults(&req) | ||
|
|
||
| if req.SnapshotReserveFactor < 1 { | ||
| restutils.SendHTTPError(ctx, w, http.StatusBadRequest, | ||
| errors.New("invalid snapshot reserve factor")) | ||
| return | ||
| return http.StatusBadRequest, errors.New("invalid snapshot reserve factor") | ||
| } | ||
|
|
||
| if err := bricksplanner.PlanBricks(&req); err != nil { | ||
| restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) | ||
| return | ||
| return http.StatusInternalServerError, err | ||
| } | ||
| } else { | ||
| if err := checkDupBrickEntryVolCreate(req); err != nil { | ||
| restutils.SendHTTPError(ctx, w, http.StatusBadRequest, err) | ||
| return | ||
| return http.StatusBadRequest, err | ||
| } | ||
| } | ||
|
|
||
| req.Options, err = expandGroupOptions(req.Options) | ||
| if err != nil { | ||
| restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) | ||
| return | ||
| return http.StatusInternalServerError, err | ||
| } | ||
|
|
||
| if err := validateOptions(req.Options, req.VolOptionFlags); err != nil { | ||
| restutils.SendHTTPError(ctx, w, http.StatusBadRequest, err) | ||
| return | ||
| return http.StatusBadRequest, err | ||
| } | ||
|
|
||
| // Include default Volume Options profile | ||
|
|
@@ -171,21 +192,17 @@ func volumeCreateHandler(w http.ResponseWriter, r *http.Request) { | |
|
|
||
| nodes, err := req.Nodes() | ||
| if err != nil { | ||
| restutils.SendHTTPError(ctx, w, http.StatusBadRequest, err) | ||
| return | ||
| return http.StatusBadRequest, err | ||
| } | ||
|
|
||
| txn, err := transactionv2.NewTxnWithLocks(ctx, req.Name) | ||
| if err != nil { | ||
| status, err := restutils.ErrToStatusCode(err) | ||
| restutils.SendHTTPError(ctx, w, status, err) | ||
| return | ||
| return restutils.ErrToStatusCode(err) | ||
| } | ||
| defer txn.Done() | ||
|
|
||
| if volume.Exists(req.Name) { | ||
| restutils.SendHTTPError(ctx, w, http.StatusBadRequest, gderrors.ErrVolExists) | ||
| return | ||
| return http.StatusBadRequest, gderrors.ErrVolExists | ||
| } | ||
|
|
||
| txn.Steps = []*transaction.Step{ | ||
|
|
@@ -219,8 +236,7 @@ func volumeCreateHandler(w http.ResponseWriter, r *http.Request) { | |
| } | ||
|
|
||
| if err := txn.Ctx.Set("req", &req); err != nil { | ||
| restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) | ||
| return | ||
| return http.StatusInternalServerError, err | ||
| } | ||
|
|
||
| // Add attributes to the span with info that can be viewed along with traces. | ||
|
|
@@ -231,28 +247,8 @@ func volumeCreateHandler(w http.ResponseWriter, r *http.Request) { | |
| ) | ||
|
|
||
| if err := txn.Do(); err != nil { | ||
| status, err := restutils.ErrToStatusCode(err) | ||
| restutils.SendHTTPError(ctx, w, status, err) | ||
| return | ||
| return restutils.ErrToStatusCode(err) | ||
| } | ||
|
|
||
| volinfo, err := volume.GetVolume(req.Name) | ||
| if err != nil { | ||
| // FIXME: If volume was created successfully in the txn above and | ||
| // then the store goes down by the time we reach here, what do | ||
| // we return to the client ? | ||
| restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) | ||
| return | ||
| } | ||
|
|
||
| logger.WithField("volume-name", volinfo.Name).Info("new volume created") | ||
| events.Broadcast(volume.NewEvent(volume.EventVolumeCreated, volinfo)) | ||
|
|
||
| resp := createVolumeCreateResp(volinfo) | ||
| restutils.SetLocationHeader(r, w, volinfo.Name) | ||
| restutils.SendHTTPResponse(ctx, w, http.StatusCreated, resp) | ||
| } | ||
|
|
||
| func createVolumeCreateResp(v *volume.Volinfo) *api.VolumeCreateResp { | ||
| return (*api.VolumeCreateResp)(volume.CreateVolumeInfoResp(v)) | ||
| return http.StatusCreated, nil | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| package volume | ||
|
|
||
| const ( | ||
| // BlockHosted is plugin name for FilterBlockHostedVolumes | ||
| BlockHosted = "block-hosted" | ||
| ) | ||
|
|
||
| // Filter will receive a slice of *Volinfo and filters out the undesired one and return slice of desired one only | ||
| type Filter func([]*Volinfo) []*Volinfo | ||
|
|
||
| var filters = make(map[string]Filter) | ||
|
|
||
| // InstallFilter will register a custom Filter | ||
| func InstallFilter(name string, f Filter) { | ||
| filters[name] = f | ||
| } | ||
|
|
||
| // ApplyFilters applies all registered filters passed in the args to a slice of *Volinfo | ||
| func ApplyFilters(volumes []*Volinfo, names ...string) []*Volinfo { | ||
| for _, name := range names { | ||
| if filter, found := filters[name]; found { | ||
| volumes = filter(volumes) | ||
| } | ||
| } | ||
| return volumes | ||
| } | ||
|
|
||
| // ApplyCustomFilters applies all custom filter to a slice of *Volinfo | ||
| func ApplyCustomFilters(volumes []*Volinfo, filters ...Filter) []*Volinfo { | ||
| for _, filter := range filters { | ||
| volumes = filter(volumes) | ||
| } | ||
|
|
||
| return volumes | ||
| } | ||
|
|
||
| // FilterBlockHostedVolumes filters out volume which are suitable for hosting block volume | ||
| func FilterBlockHostedVolumes(volumes []*Volinfo) []*Volinfo { | ||
| var volInfos []*Volinfo | ||
| for _, volume := range volumes { | ||
| val, found := volume.Metadata[BlockHosting] | ||
| if found && val == "yes" { | ||
| volInfos = append(volInfos, volume) | ||
| } | ||
| } | ||
| return volInfos | ||
| } | ||
|
|
||
| func init() { | ||
| InstallFilter(BlockHosted, FilterBlockHostedVolumes) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package volume | ||
|
|
||
| const ( | ||
| // BlockHostingAvailableSize is a volume metadata to store available size of hosting volume to create block devices. | ||
| BlockHostingAvailableSize = "_block-hosting-available-size" | ||
| // BlockHostingVolumeAutoCreated is volume metadata which will be set as `yes` if gd2 auto create the hosting volume | ||
| BlockHostingVolumeAutoCreated = "block-hosting-volume-auto-created" | ||
| // BlockHosting is a volume metadata which will be set as `yes' for volumes which are able to host block devices. | ||
| BlockHosting = "block-hosting" | ||
| ) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 needs to be commented?