diff options
| author | Varun Shastry <vshastry@redhat.com> | 2014-06-04 15:01:14 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2014-06-13 09:56:39 -0700 | 
| commit | 17f366722124cef253822ba3d78c560e766cb242 (patch) | |
| tree | 4b1bfa4920b3419e87723d849d200cf7ef757009 | |
| parent | a41f212e4b5bf74e2752370de10b754a1fa3f675 (diff) | |
extras: bash command completion for gluster
Change-Id: Ifd6e68b0288dc65e41e467b4ad02bfc3bded341f
BUG: 1108767
Signed-off-by: Varun Shastry <vshastry@redhat.com>
Reviewed-on: http://review.gluster.org/7979
Reviewed-by: Lalatendu Mohanty <lmohanty@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
| -rw-r--r-- | extras/Makefile.am | 6 | ||||
| -rw-r--r-- | extras/command-completion/Makefile | 6 | ||||
| -rw-r--r-- | extras/command-completion/README | 5 | ||||
| -rw-r--r-- | extras/command-completion/gluster.bash | 492 | ||||
| -rw-r--r-- | glusterfs.spec.in | 9 | 
5 files changed, 516 insertions, 2 deletions
diff --git a/extras/Makefile.am b/extras/Makefile.am index 525fa97383c..9395c9c1b65 100644 --- a/extras/Makefile.am +++ b/extras/Makefile.am @@ -1,7 +1,8 @@  EditorModedir = $(docdir)  EditorMode_DATA = glusterfs-mode.el glusterfs.vim -SUBDIRS = init.d systemd benchmarking hook-scripts $(OCF_SUBDIR) LinuxRPM geo-rep +SUBDIRS = init.d systemd benchmarking hook-scripts $(OCF_SUBDIR) LinuxRPM \ +          geo-rep  confdir = $(sysconfdir)/glusterfs  conf_DATA = glusterfs-logrotate gluster-rsyslog-7.2.conf gluster-rsyslog-5.8.conf \ @@ -16,7 +17,8 @@ EXTRA_DIST = $(conf_DATA) specgen.scm MacOSX/Portfile glusterfs-mode.el        \  	glusterfs.vim migrate-unify-to-distribute.sh backend-xattr-sanitize.sh \  	backend-cleanup.sh disk_usage_sync.sh clear_xattrs.sh                  \  	glusterd-sysconfig glusterd.vol post-upgrade-script-for-quota.sh       \ -	pre-upgrade-script-for-quota.sh +	pre-upgrade-script-for-quota.sh command-completion/gluster.bash        \ +        command-completion/Makefile command-completion/README  install-data-local:  	$(mkdir_p) $(DESTDIR)$(localstatedir)/lib/glusterd/groups diff --git a/extras/command-completion/Makefile b/extras/command-completion/Makefile new file mode 100644 index 00000000000..06cbfe0672f --- /dev/null +++ b/extras/command-completion/Makefile @@ -0,0 +1,6 @@ +install: +	mkdir -p /etc/bash_completion.d +	cp gluster.bash /etc/bash_completion.d/gluster + +uninstall: +	rm -f /etc/bash_completion.d/gluster diff --git a/extras/command-completion/README b/extras/command-completion/README new file mode 100644 index 00000000000..0acba38168f --- /dev/null +++ b/extras/command-completion/README @@ -0,0 +1,5 @@ +This file is not moved to /etc/bash_completion.d/ with the source installation. +Please execute make install explicity from here to move this file to +/etc/bash_completion.d + +Similarly, use make uninstall to remove it from /etc/bash_completion.d diff --git a/extras/command-completion/gluster.bash b/extras/command-completion/gluster.bash new file mode 100644 index 00000000000..be0591c7211 --- /dev/null +++ b/extras/command-completion/gluster.bash @@ -0,0 +1,492 @@ +#!/bin/bash + +if pidof glusterd > /dev/null 2>&1; then +        GLUSTER_SET_OPTIONS=" +        $(for token in `gluster volume set help 2>/dev/null | grep "^Option:" | cut -d ' ' -f 2` +        do +                echo "{$token}," +        done) +        " +        GLUSTER_RESET_OPTIONS="$GLUSTER_SET_OPTIONS" +fi + +GLUSTER_TOP_SUBOPTIONS1=" +        {nfs}, +        {brick}, +        {list-cnt} +" +GLUSTER_TOP_SUBOPTIONS2=" +        {bs +                {__SIZE +                        {count} +                } +        }, +        {brick}, +        {list-cnt} +" +GLUSTER_TOP_OPTIONS=" +        {open +                [ $TOP_SUBOPTIONS1 ] +        }, +        {read +                [ $TOP_SUBOPTIONS1 ] +        }, +        {write +                [ $TOP_SUBOPTIONS1 ] +        }, +        {opendir +                [ $TOP_SUBOPTIONS1 ] +        }, +        {readdir +                [ $TOP_SUBOPTIONS1 ] +        }, +        {clear +                [ $TOP_SUBOPTIONS1 ] +        }, +        {read-perf +                [ $TOP_SUBOPTIONS2 ] +        }, +        {write-perf +                [ $TOP_SUBOPTIONS2 ] +        } +" + +GLUSTER_QUOTA_OPTIONS=" +        {enable}, +        {disable}, +        {list}, +        {remove}, +        {default-soft-limit}, +        {limit-usage}, +        {alert-time}, +        {soft-timeout}, +        {hard-timeout} +" + +GLUSTER_PROFILE_OPTIONS=" +        {start}, +        {info [ +                {peek}, +                {incremental +                        {peek} +                }, +                {cumulative}, +                {clear}, +              ] +        }, +        {stop} +" + +GLUSTER_BARRIER_OPTIONS=" +        {enable}, +        {disable} +" + +GLUSTER_GEO_REPLICATION_SUBOPTIONS=" +" +GLUSTER_GEO_REPLICATION_OPTIONS=" +        {__VOLNAME [ +                {__SLAVEURL [ +                        {create [ +                                {push-pem +                                        {force} +                                }, +                                {force} +                                ] +                        }, +                        {start {force} }, +                        {status {detail} }, +                        {config}, +                        {pause {force} }, +                        {resume {force} }, +                        {stop {force} }, +                        {delete {force} } +                            ] +                }, +                {status} +                   ] +        }, +        {status} +" + +GLUSTER_VOLUME_OPTIONS=" +        {volume [ +                {add-brick +                        {__VOLNAME} +                }, +                {barrier +                        {__VOLNAME +                                [ $GLUSTER_BARRIER_OPTIONS ] +                        } +                }, +                {clear-locks +                        {__VOLNAME} +                }, +                {create}, +                {delete +                        {__VOLNAME} +                }, +                {geo-replication +                        [ $GLUSTER_GEO_REPLICATION_OPTIONS ] +                }, +                {heal +                        {__VOLNAME} +                }, +                {help}, +                {info +                        {__VOLNAME} +                }, +                {list}, +                {log +                        {__VOLNAME} +                }, +                {profile +                        {__VOLNAME +                                [ $GLUSTER_PROFILE_OPTIONS ] +                        } +                }, +                {quota +                        {__VOLNAME +                                [ $GLUSTER_QUOTA_OPTIONS ] +                        } +                }, +                {rebalance +                        {__VOLNAME} +                }, +                {remove-brick +                        {__VOLNAME} +                }, +                {replace-brick +                        {__VOLNAME} +                }, +                {reset +                        {__VOLNAME +                                [ $GLUSTER_RESET_OPTIONS ] +                        } +                }, +                {set +                        {__VOLNAME +                                [ $GLUSTER_SET_OPTIONS ] +                        } +                }, +                {start +                        {__VOLNAME +                                {force} +                        } +                }, +                {statedump +                        {__VOLNAME} +                }, +                {status +                        {__VOLNAME} +                }, +                {stop +                        {__VOLNAME +                                {force} +                        } +                }, +                {sync +                        {__HOSTNAME} +                }, +                {top +                        {__VOLNAME +                                [ $GLUSTER_TOP_OPTIONS ] +                        } +                } +                ] +        } +" + +GLUSTER_COMMAND_TREE=" +{gluster [ +        $GLUSTER_VOLUME_OPTIONS , +        {peer [ +              {probe +                      {__HOSTNAME} +              }, +              {detach +                      {__HOSTNAME +                                {force} +                      } +              }, +              {status} +              ] +        }, +        {pool +                {list} +        }, +        {help} +        ] +}" + +__SIZE () +{ +        return 0 +} + +__SLAVEURL () +{ +        return 0 +} + +__HOSTNAME () +{ +        local zero=0 +        local ret=0 +        local cur_word="$2" + +        if [ "$1" == "X" ]; then +                return + +        elif [ "$1" == "match" ]; then +                return 0 + +        elif [ "$1" == "complete" ]; then +                COMPREPLY=($(compgen -A hostname -- $cur_word)) +        fi +        return 0 +} + +__VOLNAME () +{ +        local zero=0 +        local ret=0 +        local cur_word="$2" +        local list="" + +        if [ "X$1" == "X" ]; then +                return + +        elif [ "$1" == "match" ]; then +                return 0 + +        elif [ "$1" == "complete" ]; then +                if ! pidof glusterd > /dev/null 2>&1; then +                        list=''; + +                else +                        list=`gluster volume list 2> /dev/null` +                fi + +        else +                return 0 +        fi + +        COMPREPLY=($(compgen -W "$list" -- $cur_word)) +        return 0 +} + +_gluster_throw () { +#echo $1 >&2 +        COMPREPLY='' +        exit +} + +declare FINAL_LIST='' +declare LIST='' +declare -i TOP=0 +_gluster_push () { +        TOP=$((TOP + 1)) +        return $TOP +} +_gluster_pop () { +        TOP=$((TOP - 1)) +        return $TOP +} + +_gluster_goto_end () +{ +        local prev_top=$1 +        local top=$1 +        local token='' + +        while [ $top -ge $prev_top ]; do +                read -r token +                case $token in +                '{' | '[') +                        _gluster_push +                        top=$? +                        ;; +                '}' | ']') +                        _gluster_pop +                        top=$? +                        ;; +                esac +        done + +        return +} + +_gluster_form_list () +{ +        local token='' +        local top=0 +        local comma='' +        local cur_word="$1" + +        read -r token +        case $token in +        ']') +                ;; +        '{') +                _gluster_push +                top=$? +                read -r key +                if [ "X$cur_word" == "X" -o "${cur_word:0:1}" == "${key:0:1}" -o "${key:0:1}" == "_" ]; then +                        LIST="$LIST $key" +                fi + +                _gluster_goto_end $top +                read -r comma +                if [ "$comma" == "," ]; then +                        _gluster_form_list $cur_word +                fi +                ;; +        *) +                _gluster_throw "Expected '{' but received $token" +                ;; +        esac + +        return +} + +_gluster_goto_child () +{ +        local match_string="$1" +        local token='' +        local top=0 +        local comma='' + +        read -r token +        case $token in +        '{') +                _gluster_push +                top=$? +                ;; +        *) +                _gluster_throw "Expected '{' but received $token" +                ;; +        esac + +        read -r token +        case `echo $token` in +        '[' | ']' | '{' | '}') +                _gluster_throw "Expected string but received $token" +                ;; +        _*) +                $token "match" $match_string +                ret=$? +                if [ $ret -eq 0 ]; then +                        return +                else +                        _gluster_goto_end $top + +                        read -r comma +                        if [ "$comma" == "," ]; then +                                _gluster_goto_child $match_string +                        fi +                fi +                ;; + +        "$match_string") +                return +                ;; +        *) +                _gluster_goto_end $top + +                read -r comma +                if [ "$comma" == "," ]; then +                        _gluster_goto_child $match_string +                fi +                ;; +        esac + +        return +} + +_gluster_does_match () +{ +        local token="$1" +        local key="$2" + +        if [ "${token:0:1}" == "_" ]; then +                $token $2 +                return $? +        fi + +        [ "$token" == "$key" ] && return 0 + +        return 1 +} + +_gluster_parse () +{ +        local i=0 +        local token='' +        local tmp_token='' +        local word='' + +        while [ $i -lt $COMP_CWORD ]; do +                read -r token +                case $token in +                '[') +                        _gluster_push +                        _gluster_goto_child ${COMP_WORDS[$i]} +                        ;; +                '{') +                        _gluster_push +                        read -r tmp_token +                        _gluster_does_match $tmp_token ${COMP_WORDS[$i]} +                        if [ $? -ne 0 ]; then +                                _gluster_throw "No match" +                        fi +                        ;; +                esac +                i=$((i+1)) +        done + +        read -r token +        if [ "$token" == '[' ]; then +                _gluster_push +                _gluster_form_list ${COMP_WORDS[COMP_CWORD]} + +        elif [ "$token" == '{' ]; then +                read -r tmp_token +                LIST="$tmp_token" +        fi + +        echo $LIST +} + +_gluster_handle_list () +{ +        local list="${!1}" +        local cur_word=$2 +        local count=0 +        local i=0 + +        for i in `echo $list`; do +                count=$((count + 1)) +        done + +        if [ $count -eq 1 ] && [ "${i:0:1}" == "_" ]; then +                $i "complete" $cur_word +        else +                COMPREPLY=($(compgen -W "$list" -- $cur_word)) +        fi +        return +} + +_gluster_completion () +{ +        FINAL_LIST=`echo $GLUSTER_COMMAND_TREE |                              \ +                egrep -ao --color=never "([A-Za-z0-9_-.]+)|[[:space:]]+|." |  \ +                        egrep -v --color=never "^[[:space:]]*$" |             \ +                                _gluster_parse` + +        ARG="FINAL_LIST" +        _gluster_handle_list $ARG ${COMP_WORDS[COMP_CWORD]} +        return +} + +complete -F _gluster_completion gluster diff --git a/glusterfs.spec.in b/glusterfs.spec.in index 72ad7311806..525822a53a9 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in @@ -702,6 +702,11 @@ install -p -m 0744 extras/hook-scripts/S56glusterd-geo-rep-create-post.sh \  find ./tests ./run-tests.sh -type f | cpio -pd %{buildroot}%{_prefix}/share/glusterfs +## Install bash completion for cli +install -p -m 0744 -D extras/command-completion/gluster.bash \ +    %{buildroot}%{_sysconfdir}/bash_completion.d/gluster + +  %clean  rm -rf %{buildroot} @@ -868,6 +873,7 @@ fi  %files cli  %{_sbindir}/gluster  %{_mandir}/man8/gluster.8* +%{_sysconfdir}/bash_completion.d/gluster  %files devel  %{_includedir}/glusterfs @@ -1022,6 +1028,9 @@ fi  %ghost      %attr(0600,-,-) %{_sharedstatedir}/glusterd/nfs/run/nfs.pid  %changelog +* Thu Jun 12 2014 Varun Shastry <vshastry@redhat.com> +- Add bash completion config to the cli package +  * Thu May 22 2014 Poornima G <pgurusid@redhat.com>  - Rename old hookscripts in an RPM-standard way.  | 
