glusterfs
518 строк · 11.8 Кб
1#!/bin/bash
2
3GLUSTER_TOP_SUBOPTIONS1="
4{nfs},
5{brick},
6{list-cnt}
7"
8GLUSTER_TOP_SUBOPTIONS2="
9{bs
10{__SIZE
11{count}
12}
13},
14{brick},
15{list-cnt}
16"
17GLUSTER_TOP_OPTIONS="
18{open
19[ $GLUSTER_TOP_SUBOPTIONS1 ]
20},
21{read
22[ $GLUSTER_TOP_SUBOPTIONS1 ]
23},
24{write
25[ $GLUSTER_TOP_SUBOPTIONS1 ]
26},
27{opendir
28[ $GLUSTER_TOP_SUBOPTIONS1 ]
29},
30{readdir
31[ $GLUSTER_TOP_SUBOPTIONS1 ]
32},
33{clear
34[ $GLUSTER_TOP_SUBOPTIONS1 ]
35},
36{read-perf
37[ $GLUSTER_TOP_SUBOPTIONS2 ]
38},
39{write-perf
40[ $GLUSTER_TOP_SUBOPTIONS2 ]
41}
42"
43
44GLUSTER_QUOTA_OPTIONS="
45{enable},
46{disable},
47{list},
48{remove},
49{default-soft-limit},
50{limit-usage},
51{alert-time},
52{soft-timeout},
53{hard-timeout}
54"
55
56GLUSTER_PROFILE_OPTIONS="
57{start},
58{info [
59{peek},
60{incremental
61{peek}
62},
63{cumulative},
64{clear},
65]
66},
67{stop}
68"
69
70GLUSTER_BARRIER_OPTIONS="
71{enable},
72{disable}
73"
74
75GLUSTER_GEO_REPLICATION_SUBOPTIONS="
76"
77GLUSTER_GEO_REPLICATION_OPTIONS="
78{status},
79{__VOLNAME [
80{status},
81{__SECONDARYURL [
82{create [
83{push-pem
84{force}
85},
86{force}
87]
88},
89{start {force} },
90{status {detail} },
91{config},
92{pause {force} },
93{resume {force} },
94{stop {force} },
95{delete {force} }
96]
97}
98]
99}
100"
101
102GLUSTER_VOLUME_OPTIONS="
103{volume [
104{add-brick
105{__VOLNAME}
106},
107{barrier
108{__VOLNAME
109[ $GLUSTER_BARRIER_OPTIONS ]
110}
111},
112{clear-locks
113{__VOLNAME}
114},
115{create},
116{delete
117{__VOLNAME}
118},
119{geo-replication
120[ $GLUSTER_GEO_REPLICATION_OPTIONS ]
121},
122{heal
123{__VOLNAME}
124},
125{help},
126{info
127{__VOLNAME}
128},
129{list},
130{log
131{__VOLNAME}
132},
133{profile
134{__VOLNAME
135[ $GLUSTER_PROFILE_OPTIONS ]
136}
137},
138{quota
139{__VOLNAME
140[ $GLUSTER_QUOTA_OPTIONS ]
141}
142},
143{rebalance
144{__VOLNAME}
145},
146{remove-brick
147{__VOLNAME}
148},
149{replace-brick
150{__VOLNAME}
151},
152{reset
153{__VOLNAME
154{__VOLOPTIONS
155},
156}
157},
158{set
159{__VOLNAME
160{__VOLOPTIONS
161},
162}
163},
164{start
165{__VOLNAME
166{force}
167}
168},
169{statedump
170{__VOLNAME}
171},
172{status
173{__VOLNAME}
174},
175{stop
176{__VOLNAME
177{force}
178}
179},
180{sync
181{__HOSTNAME}
182},
183{top
184{__VOLNAME
185[ $GLUSTER_TOP_OPTIONS ]
186}
187}
188]
189}
190"
191
192GLUSTER_COMMAND_TREE="
193{gluster [
194$GLUSTER_VOLUME_OPTIONS ,
195{peer [
196{probe
197{__HOSTNAME}
198},
199{detach
200{__HOSTNAME
201{force}
202}
203},
204{status}
205]
206},
207{pool
208{list}
209},
210{help}
211]
212}"
213
214func_return=""
215
216__SIZE ()
217{
218func_return="SIZE"
219return 0
220}
221
222__SECONDARYURL ()
223{
224func_return="SECONDARYURL"
225return 0
226}
227
228__HOSTNAME ()
229{
230local zero=0
231local ret=0
232local cur_word="$2"
233
234if [ "$1" == "X" ]; then
235return
236
237elif [ "$1" == "match" ]; then
238return 0
239
240elif [ "$1" == "complete" ]; then
241func_return=`echo $(compgen -A hostname -- $cur_word)`
242fi
243return 0
244}
245
246__VOLNAME ()
247{
248local zero=0
249local ret=0
250local cur_word="$2"
251local list=""
252
253if [ "X$1" == "X" ]; then
254return
255
256elif [ "$1" == "match" ]; then
257return 0
258
259elif [ "$1" == "complete" ]; then
260if ! pidof glusterd > /dev/null 2>&1; then
261list='';
262
263else
264list=`gluster volume list 2> /dev/null`
265fi
266
267else
268return 0
269fi
270
271func_return=`echo $(compgen -W "$list" -- $cur_word)`
272return 0
273}
274
275__VOLOPTIONS()
276{
277local zero=0
278local ret=0
279local cur_word="$2"
280local list=""
281
282if [ "X$1" == "X" ]; then
283return
284
285elif [ "$1" == "match" ]; then
286return 0
287
288elif [ "$1" == "complete" ]; then
289if ! pidof glusterd > /dev/null 2>&1; then
290list='';
291else
292list=`gluster volume set help 2>/dev/null | grep "^Option:" | cut -d ' ' -f 2`
293fi
294else
295return 0
296fi
297
298func_return=`echo $(compgen -W "$list" -- $cur_word)`
299
300return 0
301}
302
303_gluster_throw () {
304#echo $1 >&2
305COMPREPLY=''
306exit
307}
308
309declare GLUSTER_FINAL_LIST=''
310declare GLUSTER_LIST=''
311declare -i GLUSTER_TOP=0
312_gluster_push () {
313GLUSTER_TOP=$((GLUSTER_TOP + 1))
314return $GLUSTER_TOP
315}
316_gluster_pop () {
317GLUSTER_TOP=$((GLUSTER_TOP - 1))
318return $GLUSTER_TOP
319}
320
321_gluster_goto_end ()
322{
323local prev_top=$1
324local top=$1
325local token=''
326
327while [ $top -ge $prev_top ]; do
328read -r token
329case $token in
330'{' | '[')
331_gluster_push
332top=$?
333;;
334'}' | ']')
335_gluster_pop
336top=$?
337;;
338esac
339done
340
341return
342}
343
344_gluster_form_list ()
345{
346local token=''
347local top=0
348local comma=''
349local cur_word="$1"
350
351read -r token
352case $token in
353']')
354;;
355'{')
356_gluster_push
357top=$?
358read -r key
359if [ "X$cur_word" == "X" -o "${cur_word:0:1}" == "${key:0:1}" -o "${key:0:1}" == "_" ]; then
360GLUSTER_LIST="$GLUSTER_LIST $key"
361fi
362
363_gluster_goto_end $top
364read -r comma
365if [ "$comma" == "," ]; then
366_gluster_form_list $cur_word
367fi
368;;
369*)
370_gluster_throw "Expected '{' but received $token"
371;;
372esac
373
374return
375}
376
377_gluster_goto_child ()
378{
379local match_string="$1"
380local token=''
381local top=0
382local comma=''
383
384read -r token
385case $token in
386'{')
387_gluster_push
388top=$?
389;;
390*)
391_gluster_throw "Expected '{' but received $token"
392;;
393esac
394
395read -r token
396case `echo $token` in
397'[' | ']' | '{' | '}')
398_gluster_throw "Expected string but received $token"
399;;
400_*)
401$token "match" $match_string
402ret=$?
403if [ $ret -eq 0 ]; then
404return
405else
406_gluster_goto_end $top
407
408read -r comma
409if [ "$comma" == "," ]; then
410_gluster_goto_child $match_string
411fi
412fi
413;;
414
415"$match_string")
416return
417;;
418*)
419_gluster_goto_end $top
420
421read -r comma
422if [ "$comma" == "," ]; then
423_gluster_goto_child $match_string
424fi
425;;
426esac
427
428return
429}
430
431_gluster_does_match ()
432{
433local token="$1"
434local key="$2"
435
436if [ "${token:0:1}" == "_" ]; then
437$token $2
438return $?
439fi
440
441[ "$token" == "$key" ] && return 0
442
443return 1
444}
445
446_gluster_parse ()
447{
448local i=0
449local token=''
450local tmp_token=''
451local word=''
452
453while [ $i -lt $COMP_CWORD ]; do
454read -r token
455case $token in
456'[')
457_gluster_push
458_gluster_goto_child ${COMP_WORDS[$i]}
459;;
460'{')
461_gluster_push
462read -r tmp_token
463_gluster_does_match $tmp_token ${COMP_WORDS[$i]}
464if [ $? -ne 0 ]; then
465_gluster_throw "No match"
466fi
467;;
468esac
469i=$((i+1))
470done
471
472read -r token
473if [ "$token" == '[' ]; then
474_gluster_push
475_gluster_form_list ${COMP_WORDS[COMP_CWORD]}
476
477elif [ "$token" == '{' ]; then
478read -r tmp_token
479GLUSTER_LIST="$tmp_token"
480fi
481
482echo $GLUSTER_LIST
483}
484
485_gluster_handle_list ()
486{
487local list="${!1}"
488local cur_word=$2
489local count=0
490local i=0
491local res=""
492
493for i in `echo $list`; do
494if [ "${i:0:1}" == "_" ]; then
495$i "complete" $cur_word
496res="$res $func_return"
497else
498res="$res $i"
499fi
500done
501
502COMPREPLY=($(compgen -W "$res" -- $cur_word))
503return
504}
505
506_gluster_completion ()
507{
508GLUSTER_FINAL_LIST=`echo $GLUSTER_COMMAND_TREE | \
509egrep -ao --color=never "([A-Za-z0-9_.-]+)|[[:space:]]+|." | \
510egrep -v --color=never "^[[:space:]]*$" | \
511_gluster_parse`
512
513ARG="GLUSTER_FINAL_LIST"
514_gluster_handle_list $ARG ${COMP_WORDS[COMP_CWORD]}
515return
516}
517
518complete -F _gluster_completion gluster
519