diff options
-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. |