4 _OVSDB_SERVER_LOCATION
=""
6 # Run ovs-vsctl and make sure that ovs-vsctl is always called with
7 # the correct --db argument.
11 if [ -n "$_OVSDB_SERVER_LOCATION" ]; then
12 _db
="--db=$_OVSDB_SERVER_LOCATION"
17 # ovs-vsctl --commands outputs in this format:
19 # main = <localopts>,<name>,<options>
20 # localopts = ([<localopt>] )*
23 # arguments = ((!argument|?argument|*argument|+argument) )*
24 # argument = ([^ ]*|argument\|argument)
26 # The [] characters in local options are just delimiters. The
27 # argument prefixes mean:
28 # !argument :: The argument is required
29 # ?argument :: The argument is optional
30 # *argument :: The argument may appear any number (0 or more) times
31 # +argument :: The argument may appear one or more times
32 # A bar (|) character in an argument means thing before bar OR thing
33 # after bar; for example, del-port can take a port or an interface.
35 _OVS_VSCTL_COMMANDS
="$(_ovs_vsctl --commands)"
37 # This doesn't complete on short arguments, so it filters them out.
38 _OVS_VSCTL_OPTIONS
="$(_ovs_vsctl --options | awk '/^--/ { print $0 }' \
39 | sed -e 's/\(.*\)=ARG/\1=/')"
42 declare -A _OVS_VSCTL_PARSED_ARGS
43 declare -A _OVS_VSCTL_NEW_RECORDS
45 # This is a convenience function to make sure that user input is
46 # looked at as a fixed string when being compared to something. $1 is
47 # the input; this behaves like 'grep "^$1"' but deals with regex
48 # metacharacters in $1.
49 _ovs_vsctl_check_startswith_string
() {
50 awk 'thearg == "" || index($0, thearg)==1' thearg
="$1"
53 # $1 = word to complete on.
54 # Complete on global options.
55 _ovs_vsctl_bashcomp_globalopt
() {
59 result
=$
(printf "%s\n" "${_OVS_VSCTL_OPTIONS}" \
60 | _ovs_vsctl_check_startswith_string
"${1%=*}")
61 if [[ $result =~
"=" ]]; then
64 printf -- "${options}\nEO\n${result}"
67 # $1 = word to complete on.
68 # Complete on local options.
69 _ovs_vsctl_bashcomp_localopt
() {
70 local options result possible_opts
72 possible_opts
=$
(printf "%s\n" "${_OVS_VSCTL_COMMANDS}" | cut
-f1 -d',')
73 # This finds all options that could go together with the
75 for prefix_arg
in $1; do
76 possible_opts
=$
(printf "%s\n" "$possible_opts" \
77 |
grep -- "\[${prefix_arg%%=*}=\?\]")
79 result
=$
(printf "%s\n" "${possible_opts}" \
80 |
tr ' ' '\n' |
tr -s '\n' |
sort |
uniq)
81 # This removes the already-seen options from the list so that
82 # users aren't completed for the same option twice.
83 for prefix_arg
in $1; do
84 result
=$
(printf "%s\n" "${result}" \
85 |
grep -v -- "\[${prefix_arg%%=*}=\?\]")
87 result
=$
(printf "%s\n" "${result}" |
sed -ne 's/\[\(.*\)\]/\1/p' \
88 | _ovs_vsctl_check_startswith_string
"$2")
89 if [[ $result =~
"=" ]]; then
92 printf -- "${options}\nEO\n${result}"
95 # $1 = given local options.
96 # $2 = word to complete on.
97 # Complete on command that could contain the given local options.
98 _ovs_vsctl_bashcomp_command
() {
99 local result possible_cmds
101 possible_cmds
=$
(printf "%s\n" "${_OVS_VSCTL_COMMANDS}")
102 for prefix_arg
in $1; do
103 possible_cmds
=$
(printf "%s\n" "$possible_cmds" \
104 |
grep -- "\[$prefix_arg=\?\]")
106 result
=$
(printf "%s\n" "${possible_cmds}" \
108 | _ovs_vsctl_check_startswith_string
"$2")
109 printf -- "${result}"
112 # $1 = completion result to check.
113 # Return 0 if the completion result is non-empty, otherwise return 1.
114 _ovs_vsctl_detect_nonzero_completions
() {
118 readarray tmp
<<< "$newarg"
119 if [ "${#tmp[@]}" -eq 1 ] && [ "${#newarg}" -eq 0 ]; then
125 # $1 = argument format to expand.
126 # Expand '+ARGUMENT' in argument format to '!ARGUMENT *ARGUMENT'.
127 _ovs_vsctl_expand_command
() {
128 result
=$
(printf "%s\n" "${_OVS_VSCTL_COMMANDS}" \
129 |
grep -- ",$1," | cut
-f3 -d',' |
tr ' ' '\n' \
130 |
awk '/\+.*/ { name=substr($0,2);
131 print "!"name; print "*"name; next; }
133 printf -- "${result}\n!--"
136 # $1 = word to complete on.
138 _ovs_vsctl_complete_table
() {
141 result
=$
(ovsdb-client
--no-heading list-tables
$_OVSDB_SERVER_LOCATION Open_vSwitch \
142 | _ovs_vsctl_check_startswith_string
"$1")
143 printf -- "EO\n%s\n" "${result}"
146 # $1 = word to complete on.
147 # Complete on record. Provide both the name and uuid.
148 _ovs_vsctl_complete_record
() {
149 local table uuids names new_record
151 table
="${_OVS_VSCTL_PARSED_ARGS[TABLE]}"
152 new_record
="${_OVS_VSCTL_NEW_RECORDS[${table^^}]}"
153 # Tables should always have an _uuid column
154 uuids
=$
(_ovs_vsctl
--no-heading -f table
-d bare
--columns=_uuid \
155 list
$table | _ovs_vsctl_check_startswith_string
"$1")
156 # Names don't always exist, silently ignore if the name column is
158 names
=$
(_ovs_vsctl
--no-heading -f table
-d bare \
159 --columns=name list
$table \
161 | _ovs_vsctl_check_startswith_string
"$1")
162 printf -- "EO\n%s\n%s\n%s\n" "${uuids}" "${names}" "${new_record}"
165 # $1 = word to complete on.
166 # Complete on bridge.
167 _ovs_vsctl_complete_bridge
() {
170 result
=$
(_ovs_vsctl list-br | _ovs_vsctl_check_startswith_string
"$1")
171 printf -- "EO\n%s\n" "${result}"
174 # $1 = word to complete on.
175 # Complete on port. If a bridge has already been specified,
176 # just complete for that bridge.
177 _ovs_vsctl_complete_port
() {
180 if [ -n "${_OVS_VSCTL_PARSED_ARGS[BRIDGE]}" ]; then
181 ports
=$
(_ovs_vsctl list-ports
"${_OVS_VSCTL_PARSED_ARGS[BRIDGE]}")
184 all_ports
=$
(_ovs_vsctl
--format=table \
188 ports
=$
(printf "$all_ports" |
tr -d '" ' |
sort -u)
190 result
=$
(_ovs_vsctl_check_startswith_string
"$1" <<< "$ports")
191 printf -- "EO\n%s\n" "${result}"
194 # $1: Atom to complete (as usual)
195 # $2: Table to complete the key in
196 # $3: Column to find keys in
197 # $4: Prefix for each completion
198 # Complete on key based on given table and column info.
199 _ovs_vsctl_complete_key_given_table_column
() {
202 keys
=$
(_ovs_vsctl
--no-heading --columns="$3" list \
204 |
tr -d '{\"}' |
tr -s ', ' '\n' | cut
-d'=' -f1 \
205 |
xargs printf "$4%s\n" | _ovs_vsctl_check_startswith_string
"$4$1")
207 printf -- "%s\n" "${result}"
210 # $1 = word to complete on.
213 # KEY is used in both br-set-external-id/br-get-external id (in
214 # which case it is implicitly a key in the external-id column) and
215 # in remove, where it is a table key. This checks to see if table
216 # is set (the remove scenario), and then decides what to do.
219 if [ -n "${_OVS_VSCTL_PARSED_ARGS[TABLE]}" ]; then
220 local column=$
(tr -d '\n' <<< ${_OVS_VSCTL_PARSED_ARGS["COLUMN"]})
221 result
=$
(_ovs_vsctl_complete_key_given_table_column \
223 ${_OVS_VSCTL_PARSED_ARGS["TABLE"]} \
227 result
=$
(_ovs_vsctl br-get-external-id \
228 ${_OVS_VSCTL_PARSED_ARGS["BRIDGE"]} \
229 | cut
-d'=' -f1 | _ovs_vsctl_check_startswith_string
"$1")
231 printf -- "%s" "${result}"
234 # $1 = word to complete on.
236 _ovs_vsctl_complete_key
() {
237 # KEY is used in both br-set-external-id/br-get-external id (in
238 # which case it is implicitly a key in the external-id column) and
239 # in remove, where it is a table key. This checks to see if table
240 # is set (the remove scenario), and then decides what to do.
243 result
="$(__complete_key $1)"
244 # If result is empty, just use user input as result.
245 if [ -z "$result" ]; then
248 printf -- "EO\n%s\n" "${result}"
251 # $1 = word to complete on.
253 _ovs_vsctl_complete_value
() {
256 # Just use user input as result.
259 printf -- "EO\n%s\n" "${result}"
262 # $1 = word to complete on.
263 # Complete on key=value.
264 _ovs_vsctl_complete_key_value
() {
265 local orig_completions new_completions
267 orig_completions
=$
(__complete_key
"$1")
268 for completion
in ${orig_completions#*EO}; do
269 new_completions
="${new_completions} ${completion}="
271 # If 'new_completions' is empty, just use user input as result.
272 if [ -z "$new_completions" ]; then
275 printf -- "NOSPACE\nEO\n%s" "${new_completions}"
278 # $1 = word to complete on.
279 # Complete on column.
280 _ovs_vsctl_complete_column
() {
283 columns
=$
(ovsdb-client
--no-headings list-columns
$_OVSDB_SERVER_LOCATION \
284 Open_vSwitch
${_OVS_VSCTL_PARSED_ARGS["TABLE"]})
285 result
=$
(printf "%s\n" "${columns}" \
286 |
tr -d ':' | cut
-d' ' -f1 \
287 | _ovs_vsctl_check_startswith_string
"$1" |
sort |
uniq)
288 printf -- "EO\n%s\n" "${result}"
291 # Extract all system interfaces.
292 _ovs_vsctl_get_sys_intf
() {
295 case "$(uname -o)" in
297 result
=$
(ip
-o link
2>/dev
/null | cut
-d':' -f2 \
298 |
sed -e 's/^ \(.*\)/\1/')
301 result
=$
(ifconfig
-a -s 2>/dev
/null | cut
-f1 -d' ' |
tail -n +2)
304 printf "%s\n" "${result}"
307 # $1 = word to complete on.
308 # Complete on system interface.
309 _ovs_vsctl_complete_sysiface
() {
312 result
=$
(_ovs_vsctl_get_sys_intf | _ovs_vsctl_check_startswith_string
"$1")
313 printf -- "EO\n%s\n" "${result}"
316 # $1 = word to complete on.
317 # Complete on interface. If a bridge has already been specified,
318 # just complete for that bridge.
319 _ovs_vsctl_complete_iface
() {
322 if [ -n "${_OVS_VSCTL_PARSED_ARGS[BRIDGE]}" ]; then
323 result
=$
(_ovs_vsctl list-ifaces
"${_OVS_VSCTL_PARSED_ARGS[BRIDGE]}")
325 for bridge
in $
(_ovs_vsctl list-br
); do
328 ifaces
=$
(_ovs_vsctl list-ifaces
"${bridge}")
329 result
="${result} ${ifaces}"
332 printf "EO\n%s\n" "${result}"
335 # $1 = word to complete on.
336 # Complete on COLUMN?:KEY=VALUE.
337 _ovs_vsctl_complete_column_optkey_value
() {
338 local result
column key value completion
340 column=$
(printf "%s\n" "$1" | cut
-d '=' -f1 | cut
-d':' -f1)
341 key
=$
(printf "%s\n" "$1" | cut
-d '=' -f1 | cut
-s -d':' -f2)
342 # The tr -d '\n' <<< makes sure that there are no leading or
343 # trailing accidental newlines.
344 table
=$
(tr -d '\n' <<< ${_OVS_VSCTL_PARSED_ARGS["TABLE"]})
345 # This might also be called after add-port or add-bond; in those
346 # cases, the table should implicitly be assumed to be "Port".
347 # This is done by checking if a NEW- parameter has been
348 # encountered and, if it has, using that type without the NEW- as
350 if [ -z "$table" ]; then
351 if [ -n ${_OVS_VSCTL_PARSED_ARGS["NEW-PORT"]} ] \
352 ||
[ -n ${_OVS_VSCTL_PARSED_ARGS["NEW-BOND-PORT"]} ]; then
356 if [ -z "$key" ]; then
357 local columns
=$
(ovsdb-client
--no-headings list-columns \
358 $_OVSDB_SERVER_LOCATION Open_vSwitch
$table)
360 result
=$
(printf "%s\n" "${columns}" \
361 |
awk '/key.*value/ { print $1":"; next }
362 { print $1; next }' \
363 | _ovs_vsctl_check_startswith_string
"$1" |
sort |
uniq)
365 if [[ $1 =~
":" ]]; then
366 result
=$
(_ovs_vsctl_complete_key_given_table_column \
367 "$key" "$table" "$column" "$column:")
369 # If result is empty, just use user input as result.
370 if [ -z "$result" ]; then
373 printf -- "NOSPACE\nEO\n%s\n" "${result}"
376 # $1 = word to complete on.
377 # Complete on filename.
378 _ovs_vsctl_complete_filename
() {
381 result
=$
(compgen
-o filenames
-A file "$1")
382 printf -- "EO\n%s\n" "${result}"
385 _ovs_vsctl_complete_bridge_fail_mode
() {
386 printf -- "EO\nstandalone\nsecure"
389 # $1 = word to complete on.
390 # Complete on target.
391 _ovs_vsctl_complete_target
() {
394 if [[ "$1" =~ ^p?u
]]; then
395 local protocol pathname expansion_base result
397 protocol
=$
(cut
-d':' -f1 <<< "$1")
398 pathname
=$
(cut
-s -d':' -f2 <<< "$1")
399 expansion_base
=$
(compgen
-W "unix punix" "$protocol")
400 expansion_base
="$expansion_base:"
401 result
=$
(compgen
-o filenames
-A file \
402 -P $expansion_base "${pathname}")
403 printf -- "NOSPACE\nEO\n%s\n" "${result}"
405 printf -- "NOSPACE\nEO\nssl:\ntcp:\nunix:\npssl:\nptcp:\npunix:"
409 # Extract PS1 prompt.
410 _ovs_vsctl_get_PS1
() {
411 if [ "$test" = "true" ]; then
416 # Original inspiration from
417 # http://stackoverflow.com/questions/10060500/bash-how-to-evaluate-ps1-ps2,
418 # but changed quite a lot to make it more robust.
420 # Make sure the PS1 used doesn't include any of the special
421 # strings used to identify the prompt
422 myPS1
="$(sed 's/Begin prompt/\\Begin prompt/; s/End prompt/\\End prompt/' <<< "$PS1")"
423 # Export the current environment in case the prompt uses any
424 vars
="$(env | cut -d'=' -f1)"
425 for var
in $vars; do export $var; done
426 funcs
="$(declare -F | cut -d' ' -f3)"
427 for func
in $funcs; do export -f $func; done
429 v
="$(bash --norc --noprofile -i 2>&1 <<< $'PS1=\"'"$myPS1"$'\" \n# Begin prompt\n# End prompt')"
430 v
="${v##*# Begin prompt}"
431 printf -- "$(tail -n +2 <<< "${v%# End prompt*}" | sed 's/\\Begin prompt/Begin prompt/; s/\\End prompt/End prompt/')"
435 # Request a new value from user. Nothing to complete on.
436 _ovs_vsctl_complete_new
() {
437 local two_word_type message result
439 if [ ! "$1" = "--" ]; then
440 two_word_type
="${2/-/ }"
441 message
="\nEnter a ${two_word_type,,}:\n$(_ovs_vsctl_get_PS1)$COMP_LINE"
445 printf -- "NOCOMP\nBM%sEM\nEO\n%s\n" "${message}" "${result}"
449 _ovs_vsctl_complete_dashdash
() {
450 printf -- "EO\n%s\n" "--"
454 # These functions are given two arguments:
456 # $1 is the word being completed
458 # $2 is the type of completion --- only currently useful for the
461 # Note that the NEW-* functions actually are ``completed''; currently
462 # the completions are just used to save the fact that they have
463 # appeared for later use (i.e. implicit table calculation).
465 # The output is of the form <options>EO<completions>, where EO stands
466 # for end options. Currently available options are:
467 # - NOSPACE: Do not add a space at the end of each completion
468 # - NOCOMP: Do not complete, but store the output of the completion
469 # func in _OVS_VSCTL_PARSED_ARGS for later usage.
470 # - BM<message>EM: Print the <message>
471 declare -A _OVS_VSCTL_ARG_COMPLETION_FUNCS
=(
472 ["TABLE"]=_ovs_vsctl_complete_table
473 ["RECORD"]=_ovs_vsctl_complete_record
474 ["BRIDGE"]=_ovs_vsctl_complete_bridge
475 ["PARENT"]=_ovs_vsctl_complete_bridge
476 ["PORT"]=_ovs_vsctl_complete_port
477 ["KEY"]=_ovs_vsctl_complete_key
478 ["VALUE"]=_ovs_vsctl_complete_value
479 ["ARG"]=_ovs_vsctl_complete_value
480 ["IFACE"]=_ovs_vsctl_complete_iface
481 ["SYSIFACE"]=_ovs_vsctl_complete_sysiface
482 ["COLUMN"]=_ovs_vsctl_complete_column
483 ["COLUMN?:KEY"]=_ovs_vsctl_complete_column_optkey_value
484 ["COLUMN?:KEY=VALUE"]=_ovs_vsctl_complete_column_optkey_value
485 ["KEY=VALUE"]=_ovs_vsctl_complete_key_value
486 ["?KEY=VALUE"]=_ovs_vsctl_complete_key_value
487 ["PRIVATE-KEY"]=_ovs_vsctl_complete_filename
488 ["CERTIFICATE"]=_ovs_vsctl_complete_filename
489 ["CA-CERT"]=_ovs_vsctl_complete_filename
490 ["MODE"]=_ovs_vsctl_complete_bridge_fail_mode
491 ["TARGET"]=_ovs_vsctl_complete_target
492 ["NEW-BRIDGE"]=_ovs_vsctl_complete_new
493 ["NEW-PORT"]=_ovs_vsctl_complete_new
494 ["NEW-BOND-PORT"]=_ovs_vsctl_complete_new
495 ["NEW-VLAN"]=_ovs_vsctl_complete_new
496 ["--"]=_ovs_vsctl_complete_dashdash
499 # $1: Argument type, may include vertical bars to mean OR
500 # $2: Beginning of completion
502 # Note that this checks for existance in
503 # _OVS_VSCTL_ARG_COMPLETION_FUNCS; if the argument type ($1) is not
504 # there it will fail gracefully.
505 _ovs_vsctl_possible_completions_of_argument
() {
506 local possible_types completions tmp
510 possible_types
=$
(printf "%s\n" "$1" |
tr '|' '\n')
511 for type in $possible_types; do
512 if [ ${_OVS_VSCTL_ARG_COMPLETION_FUNCS["${type^^}"]} ]; then
513 tmp
=$
(${_OVS_VSCTL_ARG_COMPLETION_FUNCS["${type^^}"]} \
515 tmp_noEO
="${tmp#*EO}"
517 completions
=$
(printf "%s%s\n%s" "${tmp_EO}" \
518 "${completions}" "${tmp_noEO}")
521 printf "%s\n" "${completions}"
524 # $1 = List of argument types
525 # $2 = current pointer into said list
526 # $3 = word to complete on
527 # Outputs list of possible completions
528 # The return value is the index in the cmd_args($1) list that should
529 # next be matched, if only one of them did, or 254 if there are no
530 # matches, so it doesn't know what comes next.
531 _ovs_vsctl_complete_argument
() {
532 local cmd_args arg expansion index
534 new
=$
(printf "%s\n" "$1" |
grep -- '.\+')
535 readarray
-t cmd_args
<<< "$new";
539 expansion
=$
(_ovs_vsctl_possible_completions_of_argument \
544 local tmp1 tmp2 arg2_index tmp2_noEO tmp2_EO
545 tmp1
=$
(_ovs_vsctl_possible_completions_of_argument
"${arg:1}" $3)
546 tmp2
=$
(_ovs_vsctl_complete_argument
"$1" "$(($2+1))" "$3")
548 if _ovs_vsctl_detect_nonzero_completions
"$tmp1" \
549 && _ovs_vsctl_detect_nonzero_completions
"$tmp2"; then
550 if [ "${arg:0:1}" = "*" ]; then
556 if _ovs_vsctl_detect_nonzero_completions
"$tmp1" \
557 && (! _ovs_vsctl_detect_nonzero_completions
"$tmp2"); then
558 if [ "${arg:0:1}" = "*" ]; then
564 if (! _ovs_vsctl_detect_nonzero_completions
"$tmp1") \
565 && _ovs_vsctl_detect_nonzero_completions
"$tmp2"; then
568 if (! _ovs_vsctl_detect_nonzero_completions
"$tmp1") \
569 && (! _ovs_vsctl_detect_nonzero_completions
"$tmp2"); then
572 # Don't allow secondary completions to inhibit primary
574 if [[ $tmp2 =~ ^
([^E
]|E
[^O
])*NOCOMP
]]; then
577 tmp2_noEO
="${tmp2#*EO}"
578 tmp2_EO
="${tmp2%%EO*}"
579 expansion
=$
(printf "%s%s\n%s" "${tmp2_EO}" \
580 "${tmp1}" "${tmp2_noEO}")
583 printf "%s\n" "$expansion"
587 _ovs_vsctl_detect_nospace
() {
588 if [[ $1 =~ ^
([^E
]|E
[^O
])*NOSPACE
]]; then
589 _OVS_VSCTL_COMP_NOSPACE
=true
593 _ovs_vsctl_process_messages
() {
597 message
="${message%%EM*}"
598 if [ "$test" = "true" ]; then
599 printf -- "--- BEGIN MESSAGE"
602 if [ "$test" = "true" ]; then
603 printf -- "--- END MESSAGE"
607 # colon, equal sign will mess up the completion output, just
608 # removes the colon-word and equal-word prefix from COMPREPLY items.
610 # Implementation of this function refers to the __ltrim_colon_completions
611 # function defined in bash_completion module.
613 # $1: Current argument
614 # $2: $COMP_WORDBREAKS
615 # $3: ${COMPREPLY[@]}
616 _ovs_vsctl_trim_compreply
() {
617 local cur comp_wordbreaks
621 comp_wordbreaks
=$1 && shift
624 if [[ "$cur" == *:* && "$comp_wordbreaks" == *:* ]]; then
625 local colon_word
=${cur%${cur##*:}}
626 local i
=${#compreply[*]}
628 while [ $
((--i)) -ge 0 ]; do
629 compreply
[$i]=${compreply[$i]#"$colon_word"}
633 if [[ "$cur" == *=* && "$comp_wordbreaks" == *=* ]]; then
634 local equal_word
=${cur%${cur##*=}}
635 local i
=${#compreply[*]}
636 while [ $
((--i)) -ge 0 ]; do
637 compreply
[$i]=${compreply[$i]#"$equal_word"}
641 printf "%s " "${compreply[@]}"
644 # The general strategy here is that the same functions that decide
645 # completions can also capture the necessary context for later
646 # completions. This means that there is no distinction between the
647 # processing for words that are not the current word and words that
648 # are the current word.
650 # Parsing up until the command word happens starts with everything
651 # valid; as the syntax order of ovs-vsctl is fairly strict, when types
652 # of words that preclude other words from happending can turn them
653 # off; this is controlled by valid_globals, valid_opts, and
654 # valid_commands. given_opts is used to narrow down which commands
655 # are valid based on the previously given options.
657 # After the command has been detected, the parsing becomes more
658 # complicated. The cmd_pos variable is set to 0 when the command is
659 # detected; it is used as a pointer into an array of the argument
660 # types for that given command. The argument types are stored in both
661 # cmd_args and raw_cmd as the main loop uses properties of arrays to
662 # detect certain conditions, but arrays cannot be passed to functions.
663 # To be able to deal with optional or repeatable arguments, the exit
664 # status of the function _ovs_vsctl_complete_argument represents where
665 # it has determined that the next argument will be.
666 _ovs_vsctl_bashcomp
() {
667 local words cword valid_globals cmd_args raw_cmd cmd_pos valid_globals valid_opts
670 # Does not support BASH_VERSION < 4.0
671 if [ ${BASH_VERSINFO[0]} -lt 4 ]; then
675 # Prepare the COMP_* variables based on input.
676 if [ "$1" = "test" ]; then
678 export COMP_LINE
="ovs-vsctl $2"
679 tmp
="ovs-vsctl"$
'\n'"$(tr ' ' '\n' <<< "${COMP_LINE}x
")"
681 readarray
-t COMP_WORDS \
684 export COMP_CWORD
="$((${#COMP_WORDS[@]}-1))"
686 # If not in test mode, reassembles the COMP_WORDS and COMP_CWORD
687 # using just space as word break.
688 _get_comp_words_by_ref
-n "\"'><=;|&(:" -w words
-i cword
689 COMP_WORDS
=( "${words[@]}" )
693 # Extract the conf.db path.
694 db
=$
(sed -n 's/.*--db=\([^ ]*\).*/\1/p' <<< "$COMP_LINE")
695 if [ -n "$db" ]; then
696 _OVSDB_SERVER_LOCATION
="$db"
699 # If having trouble accessing the database, return.
700 if ! _ovs_vsctl get-manager
1>/dev
/null
2>/dev
/null
; then
704 _OVS_VSCTL_PARSED_ARGS
=()
705 _OVS_VSCTL_NEW_RECORDS
=()
712 for word
in "${COMP_WORDS[@]:1:${COMP_CWORD}} "; do
713 _OVS_VSCTL_COMP_NOSPACE
=false
716 if [ $cmd_pos -gt -1 ]; then
717 local tmp tmp_noop arg possible_newindex
718 tmp
=$
(_ovs_vsctl_complete_argument
"$raw_cmd" "$cmd_pos" "$word")
721 _ovs_vsctl_detect_nospace
$tmp
722 # Remove all options.
723 tmp_noop
="${tmp#*EO}"
725 # Allow commands to specify that they should not be
727 if ! [[ $tmp =~ ^
([^E
]|E
[^O
])*NOCOMP
]]; then
728 # Directly assignment, since 'completion' is guaranteed to
730 completion
="$tmp_noop"
731 # If intermediate completion is empty, it means that the current
732 # argument is invalid. And we should not continue.
733 if [ $index -lt $COMP_CWORD ] \
734 && (! _ovs_vsctl_detect_nonzero_completions
"$completion"); then
735 _ovs_vsctl_process_messages
"BM\nCannot complete \'${COMP_WORDS[$index]}\' at index ${index}:\n$(_ovs_vsctl_get_PS1)${COMP_LINE}EM\nEO\n"
739 # Only allow messages when there is no completion
740 # printout and when on the current word.
741 if [ $index -eq $COMP_CWORD ]; then
742 _ovs_vsctl_process_messages
"${tmp}"
744 # Append the new record to _OVS_VSCTL_NEW_RECORDS.
745 _OVS_VSCTL_NEW_RECORDS
["${cmd_args[$cmd_pos]##*-}"]="${_OVS_VSCTL_NEW_RECORDS["${cmd_args[$cmd_pos]##*-}"]} $tmp_noop"
747 if [[ $cmd_pos -lt ${#cmd_args} ]]; then
748 _OVS_VSCTL_PARSED_ARGS
["${cmd_args[$cmd_pos]:1}"]=$word
750 if [ $possible_newindex -lt 254 ]; then
751 cmd_pos
=$possible_newindex
755 if [ $valid_globals == true
]; then
756 tmp
=$
(_ovs_vsctl_bashcomp_globalopt
$word)
757 _ovs_vsctl_detect_nospace
$tmp
758 completion
="${completion} ${tmp#*EO}"
760 if [ $valid_opts == true
]; then
761 tmp
=$
(_ovs_vsctl_bashcomp_localopt
"$given_opts" $word)
762 _ovs_vsctl_detect_nospace
$tmp
763 completion
="${completion} ${tmp#*EO}"
764 if [ $index -lt $COMP_CWORD ] \
765 && _ovs_vsctl_detect_nonzero_completions
"$tmp"; then
767 given_opts
="${given_opts} ${word}"
770 if [ $valid_commands = true
]; then
771 tmp
=$
(_ovs_vsctl_bashcomp_command
"$given_opts" $word)
772 _ovs_vsctl_detect_nospace
$tmp
773 completion
="${completion} ${tmp#*EO}"
774 if [ $index -lt $COMP_CWORD ] \
775 && _ovs_vsctl_detect_nonzero_completions
"$tmp"; then
780 raw_cmd
=$
(_ovs_vsctl_expand_command
"$word")
781 readarray
-t cmd_args
<<< "$raw_cmd"
784 if [ "$word" = "--" ] && [ $index -lt $COMP_CWORD ]; then
785 # Empty the parsed args array.
786 _OVS_VSCTL_PARSED_AGS
=()
788 # No longer allow global options after '--'.
794 completion
="$(sort -u <<< "$
(tr ' ' '\n' <<< ${completion})")"
795 if [ $index -eq $COMP_CWORD ]; then
796 if [ "$test" = "true" ]; then
797 completion
="$(_ovs_vsctl_trim_compreply "$word" ":=" ${completion} | \
799 if [ "${_OVS_VSCTL_COMP_NOSPACE}" = "true" ]; then
800 printf "%s" "$completion" |
sed -e '/^$/d'
802 printf "%s" "$completion" |
sed -e '/^$/d; s/$/ /g'
806 if [ "${_OVS_VSCTL_COMP_NOSPACE}" = "true" ]; then
808 COMPREPLY
=( $
(compgen
-W "${completion}" -- $word) )
811 COMPREPLY
=( $
(compgen
-W "${completion}" -- $word) )
813 COMPREPLY
=( $
(_ovs_vsctl_trim_compreply
"$word" \
814 "${COMP_WORDBREAKS}" ${COMPREPLY[@]}) )
821 if [ "$1" = "test" ]; then
822 _ovs_vsctl_bashcomp
"$@"
824 complete
-F _ovs_vsctl_bashcomp ovs-vsctl