#!/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 [ $GLUSTER_TOP_SUBOPTIONS1 ] }, {read [ $GLUSTER_TOP_SUBOPTIONS1 ] }, {write [ $GLUSTER_TOP_SUBOPTIONS1 ] }, {opendir [ $GLUSTER_TOP_SUBOPTIONS1 ] }, {readdir [ $GLUSTER_TOP_SUBOPTIONS1 ] }, {clear [ $GLUSTER_TOP_SUBOPTIONS1 ] }, {read-perf [ $GLUSTER_TOP_SUBOPTIONS2 ] }, {write-perf [ $GLUSTER_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 GLUSTER_FINAL_LIST='' declare GLUSTER_LIST='' declare -i GLUSTER_TOP=0 _gluster_push () { GLUSTER_TOP=$((GLUSTER_TOP + 1)) return $GLUSTER_TOP } _gluster_pop () { GLUSTER_TOP=$((GLUSTER_TOP - 1)) return $GLUSTER_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 GLUSTER_LIST="$GLUSTER_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 GLUSTER_LIST="$tmp_token" fi echo $GLUSTER_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 () { GLUSTER_FINAL_LIST=`echo $GLUSTER_COMMAND_TREE | \ egrep -ao --color=never "([A-Za-z0-9_.-]+)|[[:space:]]+|." | \ egrep -v --color=never "^[[:space:]]*$" | \ _gluster_parse` ARG="GLUSTER_FINAL_LIST" _gluster_handle_list $ARG ${COMP_WORDS[COMP_CWORD]} return } complete -F _gluster_completion gluster