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

Adding glustercli command to get options of all volumes #1406

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

rishubhjain
Copy link
Contributor

Fixes:#1385
Signed-off-by: rishubhjain rishubhjain47@gmail.com

@ghost ghost assigned rishubhjain Dec 14, 2018
@ghost ghost added the in progress label Dec 14, 2018
@rishubhjain
Copy link
Contributor Author

@Madhu-1 @atinmu Please review

@Madhu-1
Copy link
Member

Madhu-1 commented Dec 14, 2018

retest this please

Copy link
Member

@Madhu-1 Madhu-1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please paste the sample output for below scenario.

  • volume option for one volume
  • options for all

@rishubhjain
Copy link
Contributor Author

rishubhjain commented Dec 14, 2018

Volume option for all volumes :

[root@localhost glusterd2]# ./build/glustercli volume get all all
Volume : testvol1
+-------------------------------+----------+--------+---------------+--------------+
|             NAME              | MODIFIED | VALUE  | DEFAULT VALUE | OPTION LEVEL |
+-------------------------------+----------+--------+---------------+--------------+
| nufa.lookup-unhashed          | no       | on     | on            | Basic        |
| nufa.min-free-disk            | no       | 10%    | 10%           | Basic        |
| nufa.min-free-inodes          | no       | 5%     | 5%            | Basic        |
| nufa.rebalance-stats          | no       | off    | off           | Basic        |
| nufa.rsync-hash-regex         | no       |        |               | Basic        |
| nufa.extra-hash-regex         | no       |        |               | Basic        |
| nufa.weighted-rebalance       | no       | on     | on            | Basic        |
| nufa.rebal-throttle           | no       | normal | normal        | Basic        |
| distribute.lookup-unhashed    | no       | on     | on            | Basic        |
| distribute.min-free-disk      | no       | 10%    | 10%           | Basic        |
| distribute.min-free-inodes    | no       | 5%     | 5%            | Basic        |
| distribute.rebalance-stats    | no       | off    | off           | Basic        |
| distribute.rsync-hash-regex   | no       |        |               | Basic        |
| distribute.extra-hash-regex   | no       |        |               | Basic        |
| distribute.weighted-rebalance | no       | on     | on            | Basic        |
| distribute.rebal-throttle     | no       | normal | normal        | Basic        |
| changelog.changelog           | no       | off    | off           | Basic        |
| changelog.capture-del-path    | no       | off    | off           | Basic        |
| switch.lookup-unhashed        | no       | on     | on            | Basic        |
| switch.min-free-disk          | no       | 10%    | 10%           | Basic        |
| switch.min-free-inodes        | no       | 5%     | 5%            | Basic        |
| switch.rebalance-stats        | no       | off    | off           | Basic        |
| switch.rsync-hash-regex       | no       |        |               | Basic        |
| switch.extra-hash-regex       | no       |        |               | Basic        |
| switch.weighted-rebalance     | no       | on     | on            | Basic        |
| switch.rebal-throttle         | no       | normal | normal        | Basic        |
| quota.enable                  | no       | off    | off           | Basic        |
+-------------------------------+----------+--------+---------------+--------------+
Volume : testvol2
+-------------------------------+----------+--------+---------------+--------------+
|             NAME              | MODIFIED | VALUE  | DEFAULT VALUE | OPTION LEVEL |
+-------------------------------+----------+--------+---------------+--------------+
| quota.enable                  | no       | off    | off           | Basic        |
| nufa.lookup-unhashed          | no       | on     | on            | Basic        |
| nufa.min-free-disk            | no       | 10%    | 10%           | Basic        |
| nufa.min-free-inodes          | no       | 5%     | 5%            | Basic        |
| nufa.rebalance-stats          | no       | off    | off           | Basic        |
| nufa.rsync-hash-regex         | no       |        |               | Basic        |
| nufa.extra-hash-regex         | no       |        |               | Basic        |
| nufa.weighted-rebalance       | no       | on     | on            | Basic        |
| nufa.rebal-throttle           | no       | normal | normal        | Basic        |
| distribute.lookup-unhashed    | no       | on     | on            | Basic        |
| distribute.min-free-disk      | no       | 10%    | 10%           | Basic        |
| distribute.min-free-inodes    | no       | 5%     | 5%            | Basic        |
| distribute.rebalance-stats    | no       | off    | off           | Basic        |
| distribute.rsync-hash-regex   | no       |        |               | Basic        |
| distribute.extra-hash-regex   | no       |        |               | Basic        |
| distribute.weighted-rebalance | no       | on     | on            | Basic        |
| distribute.rebal-throttle     | no       | normal | normal        | Basic        |
| changelog.changelog           | no       | off    | off           | Basic        |
| changelog.capture-del-path    | no       | off    | off           | Basic        |
| switch.lookup-unhashed        | no       | on     | on            | Basic        |
| switch.min-free-disk          | no       | 10%    | 10%           | Basic        |
| switch.min-free-inodes        | no       | 5%     | 5%            | Basic        |
| switch.rebalance-stats        | no       | off    | off           | Basic        |
| switch.rsync-hash-regex       | no       |        |               | Basic        |
| switch.extra-hash-regex       | no       |        |               | Basic        |
| switch.weighted-rebalance     | no       | on     | on            | Basic        |
| switch.rebal-throttle         | no       | normal | normal        | Basic        |
+-------------------------------+----------+--------+---------------+--------------+

Volume option for one volume:

[root@localhost glusterd2]# ./build/glustercli volume get testvol1 all
Volume : testvol1
+-------------------------------+----------+--------+---------------+--------------+
|             NAME              | MODIFIED | VALUE  | DEFAULT VALUE | OPTION LEVEL |
+-------------------------------+----------+--------+---------------+--------------+
| changelog.changelog           | no       | off    | off           | Basic        |
| changelog.capture-del-path    | no       | off    | off           | Basic        |
| switch.lookup-unhashed        | no       | on     | on            | Basic        |
| switch.min-free-disk          | no       | 10%    | 10%           | Basic        |
| switch.min-free-inodes        | no       | 5%     | 5%            | Basic        |
| switch.rebalance-stats        | no       | off    | off           | Basic        |
| switch.rsync-hash-regex       | no       |        |               | Basic        |
| switch.extra-hash-regex       | no       |        |               | Basic        |
| switch.weighted-rebalance     | no       | on     | on            | Basic        |
| switch.rebal-throttle         | no       | normal | normal        | Basic        |
| quota.enable                  | no       | off    | off           | Basic        |
| nufa.lookup-unhashed          | no       | on     | on            | Basic        |
| nufa.min-free-disk            | no       | 10%    | 10%           | Basic        |
| nufa.min-free-inodes          | no       | 5%     | 5%            | Basic        |
| nufa.rebalance-stats          | no       | off    | off           | Basic        |
| nufa.rsync-hash-regex         | no       |        |               | Basic        |
| nufa.extra-hash-regex         | no       |        |               | Basic        |
| nufa.weighted-rebalance       | no       | on     | on            | Basic        |
| nufa.rebal-throttle           | no       | normal | normal        | Basic        |
| distribute.lookup-unhashed    | no       | on     | on            | Basic        |
| distribute.min-free-disk      | no       | 10%    | 10%           | Basic        |
| distribute.min-free-inodes    | no       | 5%     | 5%            | Basic        |
| distribute.rebalance-stats    | no       | off    | off           | Basic        |
| distribute.rsync-hash-regex   | no       |        |               | Basic        |
| distribute.extra-hash-regex   | no       |        |               | Basic        |
| distribute.weighted-rebalance | no       | on     | on            | Basic        |
| distribute.rebal-throttle     | no       | normal | normal        | Basic        |
+-------------------------------+----------+--------+---------------+--------------+

@rishubhjain
Copy link
Contributor Author

retest this please

@Madhu-1
Copy link
Member

Madhu-1 commented Dec 14, 2018

[root@localhost glusterd2]# ./build/glustercli volume get testvol1 all
+-------------------------------+----------+--------+---------------+--------------+
| NAME | MODIFIED | VALUE | DEFAULT VALUE | OPTION LEVEL |
+-------------------------------+----------+--------+---------------+--------------+
| changelog.changelog | no | off | off | Basic |
| changelog.capture-del-path | no | off | off | Basic |
| quota.enable | no | off | off | Basic |
| distribute.lookup-unhashed | no | on | on | Basic |
| distribute.min-free-disk | no | 10% | 10% | Basic |
| distribute.min-free-inodes | no | 5% | 5% | Basic |
| distribute.rebalance-stats | no | off | off | Basic |
| distribute.rsync-hash-regex | no | | | Basic |
| distribute.extra-hash-regex | no | | | Basic |
| distribute.weighted-rebalance | no | on | on | Basic |
| distribute.rebal-throttle | no | normal | normal | Basic |
| nufa.lookup-unhashed | no | on | on | Basic |
| nufa.min-free-disk | no | 10% | 10% | Basic |
| nufa.min-free-inodes | no | 5% | 5% | Basic |
| nufa.rebalance-stats | no | off | off | Basic |
| nufa.rsync-hash-regex | no | | | Basic |
| nufa.extra-hash-regex | no | | | Basic |
| nufa.weighted-rebalance | no | on | on | Basic |
| nufa.rebal-throttle | no | normal | normal | Basic |
| switch.lookup-unhashed | no | on | on | Basic |
| switch.min-free-disk | no | 10% | 10% | Basic |
| switch.min-free-inodes | no | 5% | 5% | Basic |
| switch.rebalance-stats | no | off | off | Basic |
| switch.rsync-hash-regex | no | | | Basic |
| switch.extra-hash-regex | no | | | Basic |
| switch.weighted-rebalance | no | on | on | Basic |
| switch.rebal-throttle | no | normal | normal | Basic |
+-------------------------------+----------+--------+---------------+--------------+

am i missing anything, the table you declared as the volume name field, but its missing here?

log.WithError(err).Error("error getting volume options")
failure("Error getting volume options", err, 1)
var volList []string
if volname == "all" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if the user creates a volume with the name all and want to fetch the volume option for that particular volume :D.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, we need to reserve these keywords(all, status, volume etc) and not allow volume create.

Copy link
Contributor Author

@rishubhjain rishubhjain Dec 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice Catch, should I add this to volume-create?

@aravindavk
Copy link
Member

For uniformity you can retain "Volume name" even in single volume output. Or follow convention similar to volume status

volume: <name>
TABLE

volume: <name>
TABLE

@rishubhjain
Copy link
Contributor Author

@aravindavk Made the changes, can you check if this is what you wanted?
@Madhu-1 @aravindavk The new output is #1406 (comment)


}
}
table.Render()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

print one extra line after the table

@@ -42,6 +43,11 @@ func validateVolCreateReq(req *api.VolCreateReq) error {
return gderrors.ErrInvalidVolName
}

if gutils.IsReservedKeyword(req.Name) {
errMsg := fmt.Sprintf("invalid name, volume name cannot be among GD2 reserved keywords:%v", gutils.ReservedKeywords)
return errors.New(errMsg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use fmt.Errorf

return fmt.Errorf("invalid name, volume name cannot be among GD2 reserved keywords:%v", gutils.ReservedKeywords)

@@ -31,6 +31,17 @@ const (
TiB = 1024 * GiB
)

var (
// ReservedKeywords are Glusterd2 reserved keywords
ReservedKeywords = []string{"all", "volume", "status", "list"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also include "cluster", "gluster", "brick"

@aravindavk
Copy link
Member

Issue #1385 talks about showing cluster options. But this PR only includes showing options of all volumes. Cluster options are available in https://github.com/gluster/glusterd2/blob/master/glusterd2/commands/options/commands.go#L25 and the list of valid options are maintained here https://github.com/gluster/glusterd2/blob/master/glusterd2/options/cluster.go#L29

@rishubhjain
Copy link
Contributor Author

rishubhjain commented Dec 15, 2018

[root@localhost glusterd2]# ./build/glustercli cluster get
+--------------------------------+----------+-------+---------------+
|              NAME              | MODIFIED | VALUE | DEFAULT VALUE |
+--------------------------------+----------+-------+---------------+
| cluster.brick-multiplex        | no       | off   | off           |
| cluster.max-bricks-per-process | no       | 0     | 0             |
| cluster.localtime-logging      | no       | off   | off           |
| cluster.shared-storage         | no       | off   | off           |
| cluster.op-version             | no       | 50000 | 50000         |
| cluster.max-op-version         | no       | 50000 | 50000         |
+--------------------------------+----------+-------+---------------+
[root@localhost glusterd2]# ./build/glustercli cluster set cluster.brick-multiplex 1000
Options set successfully 
[root@localhost glusterd2]# ./build/glustercli cluster get
+--------------------------------+----------+-------+---------------+
|              NAME              | MODIFIED | VALUE | DEFAULT VALUE |
+--------------------------------+----------+-------+---------------+
| cluster.shared-storage         | no       | off   | off           |
| cluster.op-version             | no       | 50000 | 50000         |
| cluster.max-op-version         | no       | 50000 | 50000         |
| cluster.brick-multiplex        | yes      | 1000  | off           |
| cluster.max-bricks-per-process | no       | 0     | 0             |
| cluster.localtime-logging      | no       | off   | off           |
+--------------------------------+----------+-------+---------------+

}
failure("Cluster option set failed", err, 1)
} else {
fmt.Printf("Options set successfully \n")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why can't you use fmt.Println()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make a big difference?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we already have a function that provides the same functionality, what's the issue in using default function?


err := client.ClusterOptionSet(api.ClusterOptionReq{
Options: copt})
if err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return err

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am returning err at line 75, am I missing something?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the advantage you are getting by doing the error check here?

var clusterOptionGetCmd = &cobra.Command{
Use: "get",
Short: helpClusterOptionGetCmd,
Args: cobra.RangeArgs(0, 1),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where you are making use of args here?

@@ -42,6 +43,10 @@ func validateVolCreateReq(req *api.VolCreateReq) error {
return gderrors.ErrInvalidVolName
}

if gutils.IsReservedKeyword(req.Name) {
return fmt.Errorf("invalid name, volume name cannot be among glusterd reserved keywords:%v", gutils.ReservedKeywords)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

glusterd or glusterd2?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a point I want to discuss, will users be always referring the glustercli daemon as gluster daemon 2 or is it just temperory.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can skip that word itself. "invalid name, volume name cannot be among reserved keywords"

@@ -42,6 +43,10 @@ func validateVolCreateReq(req *api.VolCreateReq) error {
return gderrors.ErrInvalidVolName
}

if gutils.IsReservedKeyword(req.Name) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a e2e test case of this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as mentioned for other case, please add this as well in the same issue

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these code changes are in this PR so that I would like to see an e2e in this PR itself.

)

// GetClusterOption gets cluster level options
func (c *Client) GetClusterOption() ([]api.ClusterOptionsResp, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add e2e test case of this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a part of this PR, this PR only addresses glustercli commands, I will add e2e test cases for cluster option in separate PR, please raise an issue for it will fix that issue.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why you would like to add Client library in one PR and add e2e in other PR. what the concern here?
even if you are adding a functionality for CLI, you are adding a client library.

@@ -31,6 +31,17 @@ const (
TiB = 1024 * GiB
)

var (
// ReservedKeywords are Glusterd2 reserved keywords
ReservedKeywords = []string{"all", "volume", "status", "list", "cluster", "gluster", "brick"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add comment for why we are reserving these keywords

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reserved key words is self explanatory

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to see, why we are reserving these keywords, this will help the developers who will join later.
by these comments, I don't think they will get more context why these keywords are reserved.

}
failure("Cluster option set failed", err, 1)
} else {
fmt.Printf("Options set successfully \n")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we already have a function that provides the same functionality, what's the issue in using default function?


err := client.ClusterOptionSet(api.ClusterOptionReq{
Options: copt})
if err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the advantage you are getting by doing the error check here?

@@ -42,6 +43,10 @@ func validateVolCreateReq(req *api.VolCreateReq) error {
return gderrors.ErrInvalidVolName
}

if gutils.IsReservedKeyword(req.Name) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these code changes are in this PR so that I would like to see an e2e in this PR itself.

@@ -42,6 +43,10 @@ func validateVolCreateReq(req *api.VolCreateReq) error {
return gderrors.ErrInvalidVolName
}

if gutils.IsReservedKeyword(req.Name) {
return fmt.Errorf("invalid name, volume name cannot be among glusterd reserved keywords:%v", gutils.ReservedKeywords)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

)

// GetClusterOption gets cluster level options
func (c *Client) GetClusterOption() ([]api.ClusterOptionsResp, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why you would like to add Client library in one PR and add e2e in other PR. what the concern here?
even if you are adding a functionality for CLI, you are adding a client library.

@@ -31,6 +31,17 @@ const (
TiB = 1024 * GiB
)

var (
// ReservedKeywords are Glusterd2 reserved keywords
ReservedKeywords = []string{"all", "volume", "status", "list", "cluster", "gluster", "brick"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to see, why we are reserving these keywords, this will help the developers who will join later.
by these comments, I don't think they will get more context why these keywords are reserved.

@atinmu
Copy link
Contributor

atinmu commented Dec 17, 2018

[root@localhost glusterd2]# ./build/glustercli cluster get
+--------------------------------+----------+-------+---------------+
| NAME | MODIFIED | VALUE | DEFAULT VALUE |
+--------------------------------+----------+-------+---------------+
| cluster.shared-storage | no | off | off |
| cluster.op-version | no | 50000 | 50000 |
| cluster.max-op-version | no | 50000 | 50000 |
| cluster.brick-multiplex | yes | 1000 | off |
| cluster.max-bricks-per-process | no | 0 | 0 |
| cluster.localtime-logging | no | off | off |
+--------------------------------+----------+-------+---------------+

Can we please clean up the global option tables with all the unwanted options which were defined as place holders to begin in. For eg : cluster.localtime-logging , cluster.shared-storage are not applicable. Also cluster.op-version, cluster,max-op-version values need change and it should stay with current glusterfs master.

Also I'm not particularly sure about if the cli naming convention is correct here. glustercli cluster get doesn't give a proper meaning. Would like to hear thoughts from @aravindavk @kshlm on this.

@rishubhjain
Copy link
Contributor Author

@atinmu Regarding cli naming convention in #1406 (comment), I tried to keep it uniform with volume options glustercli volume get <volname>.

Signed-off-by: rishubhjain <rishubhjain47@gmail.com>
@atinmu
Copy link
Contributor

atinmu commented Jan 4, 2019

@Madhu-1 Are we good with this PR?

Copy link
Member

@Madhu-1 Madhu-1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need small changes or else good to go.

r.NotNil(clusterOps)
}

func ClusterOptionsSet(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

am not able to find out where this is getting called?

log.WithError(err).Error("cluster option set failed")
}
failure("Cluster option set failed", err, 1)
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can remove this else block, as failure does exit 1.

@@ -27,12 +27,10 @@ type validateFunc func(string, string) error

// ClusterOptMap contains list of supported cluster-wide options, default values and value types
var ClusterOptMap = map[string]*ClusterOption{
"cluster.shared-storage": {"cluster.shared-storage", "off", OptionTypeBool, nil},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any specific reason for removing this option?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shared-storage feature isn't a need in GD2 as of now and such feature doesn't exist yet.

@@ -233,39 +233,55 @@ var volumeDeleteCmd = &cobra.Command{
}

var volumeGetCmd = &cobra.Command{
Use: "get",
Use: "get <VOLNAME|all> <key|all>",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we rename key to option as we are getting option details?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what ever we chose here (In GD1's CLI it's referred as key though), request it to be used consistently across.

@atinmu
Copy link
Contributor

atinmu commented Jan 7, 2019

Can we please close down this PR today? It's been hanging around for a while now :-)

@aravindavk
Copy link
Member

@rishubhjain please address the comments and rebase

@rishubhjain
Copy link
Contributor Author

@aravindavk Is this a GCS 1.0 blocker?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants