volgen: Code based Volfile generation#497
volgen: Code based Volfile generation#497kshlm merged 7 commits intogluster:masterfrom aravindavk:volgen2
Conversation
Ack! |
kshlm
left a comment
There was a problem hiding this comment.
Overall, I like the new volfile and entry types and methods associated with them. Much cleaner than what I had done. Makes it easier to write custom generator funtions than before. I see no problems inusing this new framework to generate graphs using templates, but that can be done a little later.
One major concern I have right now is that, there is a lot of code duplication. There are several patterns in use, which can all be simplified into standalone functions that can be reused. This will also help in later work to use templates.
I've mainly looked at the volgen and volinfo changes, and a little of the volume create request in this review. I've not looked at the changes done to other commands.
| logger.WithError(err).Error("could not prepare node list") | ||
| restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err.Error(), api.ErrCodeDefault) | ||
| return | ||
| var nodesMap = make(map[string]int) |
There was a problem hiding this comment.
You could just update nodesFromBricks to accept []Brickinfo, and pass the bricks variable you created earlier.
| if req.Arbiter != 0 { | ||
| if req.Replica != 3 || req.Arbiter != 1 { | ||
| return nil, errors.New("For arbiter configuration, replica count must be 3 and arbiter count must be 1. The 3rd brick of the replica will be the arbiter") | ||
| for idx, subvolreq := range req.Subvols { |
There was a problem hiding this comment.
The assumption here with the request is that the subvols are only 2 levels deep, which works for existing cases. But it will be nice if we were to support an arbitrary levels, which will help us implement a tiered volume much more easily in the future. This shouldn't need too much changes to the request format.
There was a problem hiding this comment.
I do have that support in Subvol struct, but not checked that in all other places now.
I need to consider, subvol.Bricks if subvol.Subvols is nil. I will work on this part later.
There was a problem hiding this comment.
I do have that support in Subvol struct, but not checked that in all other places now.
Yup. I noticed that.
| } | ||
|
|
||
| var bricks []brick.Brickinfo | ||
| for _, subvol := range volinfo.Subvols { |
There was a problem hiding this comment.
This pattern is repeated many times to get the bricks list of a volume. Please have a common method on the *Volinfo to get a list of bricks. This will also help us easily extend the volume subvol structure later on.
There was a problem hiding this comment.
just realized now that, it is used in only two places volume-create and volume-expand. VolumeCreateReq is (VolumeCreateReq->Subvols->Bricks) and VolumeExpandReq is (VolumeExpandReq->Bricks). Not easy to have common func. I moved the code to brickutils but as two func.(duplicate code not avoided but now available in single place)
| ) | ||
|
|
||
| last := volfile.RootEntry. | ||
| Add("protocol/server", vol, b). |
There was a problem hiding this comment.
This can very easily be converted to depend on the template file we have. But we can do that later.
| volfile.FileName = vol.Name | ||
|
|
||
| dht := volfile.RootEntry.Add("debug/io-stats", vol, nil).SetName(vol.Name). | ||
| Add("performance/io-threads", vol, nil). |
There was a problem hiding this comment.
All client volfiles have this section with these common xlators. There should be a single function to add these xlators that is used where required. And this can also be easily generated from a template.
There was a problem hiding this comment.
I will introduce AddMany and accept list.
There was a problem hiding this comment.
No I didn't mean this. What I want is a single function that adds this particular list of xlators in this particular order. That single function can be reused elsewhere.
|
|
||
| for subvolIdx, subvol := range vol.Subvols { | ||
| if subvol.Type == volume.SubvolReplicate { | ||
| name := fmt.Sprintf("%s-replicate-%d", vol.Name, subvolIdx) |
There was a problem hiding this comment.
We should not be programatically generating the names for replicate/ec/dist (cluster) xlators each time we generate volfiles. We should do this once when the volume is created, or when a new brick set is added to the volume and save it with the volinfo, and use the saved names here. This will allow us to also accept subvol names during volume create, which will help with migration from 3.x to 4.0.
There was a problem hiding this comment.
Nice idea.
I do have subvol name like s1, s2.. I will change the subvol name as <volname>-<subvoltype>-<idx> in subvol struct itself
There was a problem hiding this comment.
Rather than index, give it unique names, uuids. Index will become hard to keep track of after a few expansions/shrinks of the the volume.
There was a problem hiding this comment.
Yes please! This is one of my primary ask. (Hence I was asking for ability to pass the distribute subvolume name in API itself (to help with backward compatibility)).
| Add("cluster/distribute", vol, nil) | ||
|
|
||
| for subvolIdx, subvol := range vol.Subvols { | ||
| if subvol.Type == volume.SubvolReplicate { |
There was a problem hiding this comment.
Why only replicate? Wouldn't EC also require this?
Also, bricks are being added to the graph only when this condition is true. So distribute volumes don't have any bricks added to the graph.
There was a problem hiding this comment.
I didn't considered EC since EC support patch was in review. I will look into this condition again
| Add("performance/write-behind", vol, nil). | ||
| Add("cluster/distribute", vol, nil) | ||
|
|
||
| for subvolIdx, subvol := range vol.Subvols { |
There was a problem hiding this comment.
This should be made a common function as well. We will need to attach the cluster graph to other graphs several times.
There was a problem hiding this comment.
Not done as single function since bitd volfile differs with respect to local bricks. I will give it a try now.
|
@kshlm Thanks for the comments, I will address the comments and refresh the patch soon. |
|
@kshlm please review |
kshlm
left a comment
There was a problem hiding this comment.
Need some more details on how the volfiles are actually being generated for volume create and other apis.
A few more comments about refactoring code for better readability.
And my request from the previous review about a common function to add the client xlator stack is yet to be done. If this isn't something you want to do now, please let me know.
| DoFunc: "vol-create.Validate", | ||
| Nodes: nodes, | ||
| }, | ||
| { |
There was a problem hiding this comment.
When exactly are volfiles generated? I see the new volfile endpoint, but I don't understand how exactly it works.
There was a problem hiding this comment.
In $SRC/glusterd2/commands/volumes/common.go:storeVolume, Incremental generation of volfiles is not yet implemented. All the Volfiles will be (re)generated when volinfo is stored.(Create/Expand/Set etc)
| if !uuid.Equal(b.NodeID, gdctx.MyUUID) { | ||
| continue | ||
| } | ||
| for _, b := range vol.GetBricks(true) { |
There was a problem hiding this comment.
Just a small nit. The volume variable is named vol here but volinfo in the startAllBricks() function above. Isn't consistent.
There was a problem hiding this comment.
Not changed the names in existing code. I will update this.
| } | ||
|
|
||
| // Generate generates all the volfiles(Cluster/Volume/Brick) | ||
| func Generate() error { |
There was a problem hiding this comment.
This function is huge, and can be split into individual functions for generating volume volfiles, brick volfiles and cluster volfiles.
There was a problem hiding this comment.
And my request from the previous review about a common function to add the client xlator stack is yet to be done. If this isn't something you want to do now, please let me know.
Only client graph and gfproxy are using common list of xlators for now. But that may differ in future. I don't see much repeatation there.
| Type string | ||
| VolumeID uuid.UUID | ||
| BrickID uuid.UUID | ||
| ExtraOptions map[string]string |
There was a problem hiding this comment.
What's the difference between ExtraOptions and ExtraData? A comment here will help.
There was a problem hiding this comment.
I will add the details
| "github.com/pborman/uuid" | ||
| ) | ||
|
|
||
| var varStrRE = regexp.MustCompile(`\{\{\s*(\S+)\s*\}\}`) |
There was a problem hiding this comment.
Move the var string code into its own file. Keeps things much more readable.
|
|
||
| // getValue returns value if found for provided graph.xlator.keys in the options map | ||
| // XXX: Not possibly the best place for this | ||
| func getValue(graph, xl string, keys []string, opts map[string]string) (string, string, bool) { |
There was a problem hiding this comment.
getValue and getOptions can be moved into a seperate files (utils?).
| } | ||
|
|
||
| // GetBricks returns a list of Bricks | ||
| func (v *Volinfo) GetBricks(onlyLocal bool) []brick.Brickinfo { |
There was a problem hiding this comment.
It'd be nicer if this were two functions GetBricks and GetLocalBricks. Makes it much more understandable when calling from elsewhere, as you don't have any trouble understanding the true/false being passed.
This current GetBricks(bool) function can become and unexported getBricks(bool) and the newer exported GetBricks() and GetLocalBricks() functions can call it.
| type VolExpandReq struct { | ||
| ReplicaCount int `json:"replica,omitempty"` | ||
| Bricks []string `json:"bricks"` | ||
| ReplicaCount int `json:"replica,omitempty"` |
There was a problem hiding this comment.
This is okay for now. But the expected API to add bricks which aligns with the new create API, is to be able to accept a list of subvols with the new bricks/subvols. For eg.,
[
{
"SubvolID": "00adc43c-6eeb-47d9-912a-12daf6cde2c7",
"Bricks": [
{
"NodeID": "8d1c03a7-0ac8-4072-a8c2-83f31c92ccd2",
"Path": "/new/brick"
}
],
"Subvols": []
},
{
"SubvolID": "3378e563-705d-4eb0-a9a0-cb9bf2301634",
"Bricks": [
{
"NodeID": "e8986e52-bb46-4bbc-91b6-0c45b0ef1872",
"Path": "/new/brick"
}
],
"Subvols": []
}
]This will make it slightly harder for our cli, but makes the expand api way more powerful.
There was a problem hiding this comment.
This is for supporting current syntax for Volume Expand. We need to have discussion on all the Sub volume based commands. Like Add new subvol, Delete Subvol, Expand a subvol etc.
Sub volumes support is added to Volinfo. Code based volfile generation is implemented(Still exploring the possible approach to do that based on input json/yml/toml) All volfiles available in `$SRC/glusterd2/volgen2/volfile_*.go` Features: - Easy to add condition while generating volfile(For example, bitrot volfile only contains local bricks information) - Easy to generate Cluster level, Volume level and Brick level volfiles - Adding new volfile support is easy(Add one file) - Full access to Cluster Info/Volume Info/Brick Info - All supported volfiles are available now - All generated volfiles are stored in etcd - REST endpoint available to trigger regeneration of volfiles(Selective regeneration not yet available) Limitations: - Currently limited to code based volfile generation. If new volfile added or modified, Glusterd2 need to be recompiled. I tried template based approach to support cluster volfiles but it is getting over complecated. If this is not blocker now, we can proceed with this approach. Future: - Template file(json/yml/toml) support can be added on top of this if required. Fixes: #388 Signed-off-by: Aravinda VK <avishwan@redhat.com>
Signed-off-by: Aravinda VK <avishwan@redhat.com>
Merged duplicate code, simplified interface for volfiles. Now it is easy to support both interface code and template for volfile generation Signed-off-by: Aravinda VK <avishwan@redhat.com>
Signed-off-by: Aravinda VK <avishwan@redhat.com>
Added subvolume Name and ID in volume-expand Signed-off-by: Aravinda VK <avishwan@redhat.com>
Signed-off-by: Aravinda VK <avishwan@redhat.com>
Also rebased after disperse volume integration Signed-off-by: Aravinda VK <avishwan@redhat.com>
|
@kshlm updated the code and rebased again. Please review |
Sub volumes support is added to Volinfo. Code based volfile generation
is implemented(Still exploring the possible approach to do that based on
input json/yml/toml)
All volfiles available in
$SRC/glusterd2/volgen2/volfile_*.goFeatures:
volfile only contains local bricks information)
regeneration not yet available)
Limitations:
added or modified, Glusterd2 need to be recompiled. I tried template
based approach to support cluster volfiles but it is getting over
complecated. If this is not blocker now, we can proceed with this
approach.
Future:
this if required.
Fixes: #388
Signed-off-by: Aravinda VK avishwan@redhat.com