According to the manual:

"... When executing commands on a remote Xen Cloud Platform host, tab 
completion does not normally work. However if you put the server, username, and 
password in an environment variable called XE_EXTRA_ARGS on the machine from 
which you are entering the commands, tab completion is enabled. See the section 
called  Basic xe syntax  for details. ..."

However, when dealing with a large number of machines, checking/updating RC 
file or environment variable at every single call sounds like a ugly way.

This patch adds the remote server (and other config options) support to xe's 
bash completion functionality. It enables tab completion when xe calls a remote 
server whose config can be set by command line options in "-o xxx" format or 
"option=xxx" format or the mix of both. The patch should work in general 
according to my limited tests, but please bear with my poor bash skills and 
feel free to improve.

A few other minor bugs were also fixed during the process.


Signed-off-by: Zheng Li <[email protected]>


 ocaml/xe-cli/bash-completion |  322 
++++++++++++++++++++++++++++-----------------
 1 files changed, 199 insertions(+), 123 deletions(-)


diff -r ad5ea8e64ad2 -r 7d0fb4d42e65 ocaml/xe-cli/bash-completion
--- a/ocaml/xe-cli/bash-completion      Tue May 04 06:22:08 2010 +0100
+++ b/ocaml/xe-cli/bash-completion      Tue May 04 07:18:23 2010 +0100
@@ -6,24 +6,76 @@
 
 _xe()
 {
-        local IFS=$'\n,'
 
-       local cur prev opts xe IFS
+       local cur prev opts xe IFS oIFS cIFS ABORT_FLAG INGORE_FLAG SKIP_FLAG 
SKIP_OPTS SKIP_CONF COMP_OPWORD
+
+       oIFS=$' \t\n'
+       cIFS=$'\n,'
+
+       # The current script doesn't seem to have taken the compat mode into 
consideration. Using the standard 
+       # mode instead is possible but will obviously return misleading 
completions, while forcing to use compat 
+       # mode anyway will return message of unexpected format in most case 
hence become garbage. Considering the 
+       # rase usage of compat mode for interactive command (mostly as old 
script), we simply disable it here.
+       ABORT_FLAG=( '-help' '--help' '--compat')
+       IGNORE_FLAG=( '--debug' '--debug-on-fail' )
+       SKIP_FLAG=( '--nossl' )
+       SKIP_OPTS=( '-s' '-p' '-u' '-pw' '-pwf' '-h' )
+       ABORT_CONF=( 'compat=' )
+       IGNORE_CONF=( 'debug=' 'debugonfail=' )
+       SKIP_CONF=( 'server=' 'port=' 'username=' 'password=' 'passwordfile=' 
'nossl=' )
+
+       COMP_OPWORD=-1
+       i=1
+       skip=0
+       while [ $COMP_OPWORD -lt 0 ] && [ $i -lt $COMP_CWORD ]; do
+               cont=0
+               for f in ${abort_fl...@]}; do if [[ $f == ${COMP_WORDS[i]} ]]; 
then return 0; fi; done
+               for f in ${ignore_fl...@]}; do if [[ $f == ${COMP_WORDS[i]} ]]; 
then unset COMP_WORDS[$i]; cont=1; let skip=$skip+1; break; fi; done
+               if [ $cont -gt 0 ]; then let i=$i+$cont; continue; fi
+               for f in ${skip_fl...@]}; do if [[ $f == ${COMP_WORDS[i]} ]]; 
then cont=1; break; fi; done
+               if [ $cont -gt 0 ]; then let i=$i+$cont; continue; fi
+               for f in ${skip_op...@]}; do if [[ $f == ${COMP_WORDS[i]} ]]; 
then cont=2; break; fi; done
+               if [ $cont -gt 0 ]; then let i=$i+$cont; continue; fi
+               for f in ${abort_co...@]}; do if [[ $f == 
${COMP_WORDS[i]:0:${#f}} ]]; then return 0; fi; done
+               for f in ${ignore_co...@]}; do if [[ $f == 
${COMP_WORDS[i]:0:${#f}} ]]; then unset COMP_WORDS[$i]; cont=1; let 
skip=$skip+1; break; fi; done
+               if [ $cont -gt 0 ]; then let i=$i+$cont; continue; fi
+               for f in ${skip_co...@]}; do if [[ $f == 
${COMP_WORDS[i]:0:${#f}} ]]; then cont=1; break; fi; done
+               if [ $cont -gt 0 ]; then let i=$i+$cont; continue; fi
+               COMP_OPWORD=$i
+       done
+
        COMPREPLY=()
        cur="${COMP_WORDS[COMP_CWORD]}"
        prev="${COMP_WORDS[COMP_CWORD-1]}"
-       xe=xe
-       
-       if [[ $COMP_CWORD == 1 ]] ; then
-               opts=`${xe} help --minimal --all 2>/dev/null | sed -e 's/,/\ 
,/g' -e 's/$/\ /g'` && COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
+
+       optargs=`echo "${abort_fl...@]} ${ignore_fl...@]} ${skip_fl...@]} 
${skip_op...@]}" | sed -e 's/\ /\ ,/g'` 
+       eqargs=`echo "${abort_co...@]} ${ignore_co...@]} ${skip_co...@]}" | sed 
-e 's/\ /,/g'`
+       opts="$optargs ,$eqargs"
+
+
+       if [[ $COMP_OPWORD -lt 0 ]]; then
+               xe="${comp_wor...@]:0:$COMP_CWORD-$skip}"
+       else
+               xe="${comp_wor...@]:0:$COMP_OPWORD-$skip}"
+       fi
+
+       if [[ $COMP_OPWORD -lt 0 ]]; then
+               for f in ${skip_op...@]}; do if [[ $f == 
${COMP_WORDS[COMP_CWORD-1]} ]]; then return 0; fi; done
+               IFS=$oIFS
+               cmdargs=`${xe} help --minimal --all 2>/dev/null | sed -e 
's/,\|&/\ ,/g'`
+               IFS=$cIFS
+               opts="$opts,$cmdargs"
+               COMPREPLY=( $(compgen -W "${opts}" -X ${cur} -- ${cur}) )
+               IFS=$oIFS
                return 0
        fi
-       
-# parameters are passed as param=value
+
+       # parameters are passed as param=value
+
 
        if echo ${COMP_WORDS[COMP_CWORD]} | grep "=" > /dev/null; then
                local param value
-               local IFS=""
+               IFS=""
                param=`echo ${COMP_WORDS[COMP_CWORD]} | cut -d= -f1`
                value=`echo ${COMP_WORDS[COMP_CWORD]} | cut -d= -f2`
 
@@ -31,202 +83,220 @@
                
                case "$param" in
                        filename|file-name|license-file)
-                               IFS=$'\n,'
+                               IFS=$cIFS
                                COMPREPLY=( $(compgen -f ${value}) )
                                return 0
                                ;;
 
                        mode) # for pif-reconfigure-ip
-                               if [ "${COMP_WORDS[1]}" == "pif-reconfigure-ip" 
]; then
-                                       IFS=$'\n,'
+                               if [ "${COMP_WORDS[COMP_OPWORD]}" == 
"pif-reconfigure-ip" ]; then
+                                       IFS=$cIFS
                                        COMPREPLY=( $(compgen -W "dhcp ,static 
,none" -- ${value}) )
                                fi
                                return 0
                                ;;
 
-                       uuid)   
-                               case "${COMP_WORDS[1]}" in
+                       uuid)   
+                               case "${COMP_WORDS[COMP_OPWORD]}" in
                                        diagnostic-vm-status) cmd=vm-list;;
                                        diagnostic-vdi-status) cmd=vdi-list;;
-                                       *) cmd=`echo ${COMP_WORDS[1]} | awk -F- 
'/^host-cpu-/ || /^host-crashdump-/ { print $1 "-" $2 }
$0 !~ /^host-cpu-/ && $0 !~ /^host-crashdump-/ { print $1 }'`-list;;
+                                       *) cmd=`echo ${COMP_WORDS[COMP_OPWORD]} 
| awk -F- '/^host-cpu-/ || /^host-crashdump-/ { print $1 "-" $2 }
$0 !~ /^host-cpu-/ && $0 !~ /^host-crashdump-/ { print $1 }'`-list;;
                                esac
-                                IFS=$'\n,'
+                               IFS=$cIFS
                                COMPREPLY=( $(compgen_names "$cmd" uuid 
"$value") )
                                return 1
                                ;;
                        vm)
-                                IFS=$'\n,'
-                                COMPREPLY=( $(compgen_names vm-list name-label 
"$value") )
+                               IFS=$cIFS
+                               COMPREPLY=( $(compgen_names vm-list name-label 
"$value") )
                                return 0
                                ;;
 
                        host)
-                                IFS=$'\n,'
+                               IFS=$cIFS
                                COMPREPLY=( $(compgen_names host-list 
name-label "$value") )
                                return 0
                                ;;
                        params)
-                                val=$(final_comma_separated_param "$value")
-                               class=`echo ${COMP_WORDS[1]} | cut -d- -f1`
-                               params=`${xe} ${class}-list params=all 
2>/dev/null| cut -d: -f1 | sed -e s/\(.*\)//g -e s/^\ *//g -e s/\ *$//g`
-                                IFS=$'\n,'
+                               val=$(final_comma_separated_param "$value")
+                               class=`echo ${COMP_WORDS[COMP_OPWORD]} | cut 
-d- -f1`
+                               IFS=$oIFS
+                               params=`${xe} ${class}-list params=all 
2>/dev/null | cut -d: -f1 |  sed -e s/\(.*\)//g -e s/^\ *//g -e s/\ *$//g`
+                               IFS=$cIFS
                                COMPREPLY=( $(compgen -W "$params,all" -- 
"$val" ) )
                                return 0
                                ;;
                        template)
-                                IFS=$'\n,'
-                                COMPREPLY=( $(compgen_names template-list 
name-label "$value") )
+                               IFS=$cIFS
+                               COMPREPLY=( $(compgen_names template-list 
name-label "$value") )
                                return 0
                                ;;
 
                        # param name is used by *-param-add
                        param-name)
-                               if echo ${COMP_WORDS[1]} | grep "param-add" > 
/dev/null; then
-                                       class=`echo ${COMP_WORDS[1]} | sed 
s/-param-add//g`
+                               if echo ${COMP_WORDS[COMP_OPWORD]} | grep 
"param-add" > /dev/null; then
+                                       class=`echo ${COMP_WORDS[COMP_OPWORD]} 
| sed s/-param-add//g`
+                                       IFS=$oIFS
                                        paramsset=`${xe} ${class}-list 
params=all 2>/dev/null | grep "SRW\|MRW" | cut -d\( -f 1 | cut -d: -f1 | sed 
s/\ *//` 
-                                       IFS=$'\n,' COMPREPLY=( $(compgen -W 
"${paramsset}" -- ${value}) )
+                                       IFS=$cIFS 
+                                       COMPREPLY=( $(compgen -W "${paramsset}" 
-- ${value}) )
                                        return 0
                                fi
                                ;;
                        cd-name)
-                               if [[ "${COMP_WORDS[1]}" == "vm-cd-add" || 
"${COMP_WORDS[1]}" == "vm-cd-insert" ]]; then
-                                        IFS=$'\n,'
-                                        COMPREPLY=( $(compgen_names cd-list 
name-label "$value") )
+                               if [[ "${COMP_WORDS[COMP_OPWORD]}" == 
"vm-cd-add" || "${COMP_WORDS[COMP_OPWORD]}" == "vm-cd-insert" ]]; then
+                                       IFS=$cIFS
+                                       COMPREPLY=( $(compgen_names cd-list 
name-label "$value") )
                                        return 0
-                               elif [[ "${COMP_WORDS[1]}" == "vm-cd-remove" 
]]; then
-                                       vm=`for i in ${comp_wor...@]:2}; do 
echo $i | grep "^vm="; done`
+                               elif [[ "${COMP_WORDS[COMP_OPWORD]}" == 
"vm-cd-remove" ]]; then
+                                       vm=`for i in ${comp_wor...@]:2}; do 
echo $i | grep "^vm="; done`
+                                       IFS=$oIFS
                                        local cds=`${xe} vm-cd-list "$vm" 
--minimal --multiple vbd-params=vdi-name-label vdi-params=none 2>/dev/null | 
sed -e "s,',$MAGIC_SQUOTE,g" -e "s,\",$MAGIC_DQUOTE,g"`
-                                        IFS=$'\n,'
-                                        COMPREPLY=( $(compgen_escape "$cds" 
"$value") )
+                                       IFS=$cIFS
+                                       COMPREPLY=( $(compgen_escape "$cds" 
"$value") )
                                        return 0
                                fi
                                ;;
                        on)     
-                                IFS=$'\n,'
-                                COMPREPLY=( $(compgen_names host-list 
name-label "$value") )
+                               IFS=$cIFS
+                               COMPREPLY=( $(compgen_names host-list 
name-label "$value") )
                                return 0
                                ;;
                        key)
+                               IFS=$oIFS
                                local keys=`${xe} log-get-keys --minimal 
2>/dev/null`
-                                IFS=$'\n,'
-                                COMPREPLY=( $(compgen_escape "$keys" "$value") 
)
+                               IFS=$cIFS
+                               COMPREPLY=( $(compgen_escape "$keys" "$value") )
                                return 0
                                ;;
                        level)
-                                IFS=$'\n,'
+                               IFS=$cIFS
                                COMPREPLY=( $(compgen -W "debug ,info ,warning 
,error " -- ${value}) )
                                return 0
                                ;;
                        sr-name-label) # for vm-install
-                                IFS=$'\n,'
+                               IFS=$cIFS
                                COMPREPLY=( $(compgen_names sr-list name-label 
"$value") )
                                return 0
                                ;;
                        crash-dump-SR | suspend-image-SR | default-SR)
-                                IFS=$'\n,'
+                               IFS=$cIFS
                                COMPREPLY=( $(compgen_names sr-list uuid 
"$value") )
                                return 0
                                ;;
                        type) # for vbd-create/vdi-create/sr-create/sr-probe
-                                IFS=$'\n,'
-                               fst=`echo ${COMP_WORDS[1]} | cut -d- -f1`
-
+                               IFS=$cIFS
+                               fst=`echo ${COMP_WORDS[COMP_OPWORD]} | cut -d- 
-f1`
                                if [[ "${fst}" == "vbd" ]]; then
-                                  COMPREPLY=( $(compgen -W "Disk ,CD " -- 
${value}) )
-                                  return 0
+                                       COMPREPLY=( $(compgen -W "Disk ,CD " -- 
${value}) )
+                                       return 0
                                elif [[ "${fst}" == "vdi" ]]; then
-                                  COMPREPLY=( $(compgen -W "system ,user 
,suspend ,crashdump " -- ${value}) )
-                                  return 0
+                                       COMPREPLY=( $(compgen -W "system ,user 
,suspend ,crashdump " -- ${value}) )
+                                       return 0
                                elif [[ "${fst}" == "sr" ]]; then
-                                  COMPREPLY=( $(compgen -W "$(xe sm-list 
params=type --minimal 2>/dev/null | sed 's/,/ ,/g') " -- ${value}) )
-                                  return 0
+                                       IFS=$oIFS
+                                       local types=`${xe} sm-list params=type 
--minimal 2>/dev/null | sed 's/,\|$/ &/g'`
+                                       IFS=$cIFS
+                                       COMPREPLY=( $(compgen -W "$types" -- 
${value}) )
+                                       return 0
                                fi
                                ;;
                        entries) # for host-get-system-status
-                                val=$(final_comma_separated_param "$value")
-                                master_uuid=$(xe pool-list params=master 
--minimal 2>/dev/null)
-                                IFS=$'\n'
-                                caps=$($xe host-get-system-status-capabilities 
uuid="$master_uuid" 2>/dev/null | grep '<capability ' | sed -ne 
's/.*<capability .* key="\([^"]*\)".*$/\1/p' | tr '\n' , | sed -e 's/,$//g' | 
tr , '\n')
-        # Fake "
-                                COMPREPLY=( $(compgen -W "$caps" -- "$val") )
-                                return 0
-                                ;;
+                               val=$(final_comma_separated_param "$value")
+                               IFS=$oIFS
+                               master_uuid=`${xe} pool-list params=master 
--minimal 2>/dev/null`
+                               caps=`${xe} host-get-system-status-capabilities 
uuid="$master_uuid" 2>/dev/null | grep '<capability ' | sed -ne 
's/.*<capability .* key="\([^"]*\)".*$/\1/p' | tr '\n' , | sed -e 's/,\|$/\ 
&/g' | tr , '\n'`   # Fake "
+                               IFS=$cIFS
+                               COMPREPLY=( $(compgen -W "$caps" -- "$val") )
+                               return 0
+                               ;;
                        output)
-                                case "${COMP_WORDS[1]}" in
-                                    log-set-output)
-                                        IFS=$'\n,'
-                                        COMPREPLY=( $(compgen -W 
"file,syslog,nil " -- ${value}) )
-                                        ;;
-                                    host-get-system-status)
-                                        IFS=$'\n,'
-                                        COMPREPLY=( $(compgen -W "tar.bz2 ,zip 
" -- ${value}) )
-                                        ;;
-                                esac
-                                return 0
-                                ;;
-            copy-bios-strings-from) # for vm-install
-                COMPREPLY=`${xe} host-list params=uuid --minimal 2>/dev/null`
-                return 0
-                ;;
-            edition) # for host-apply-edition (licensing)
-                IFS=$'\n,'
-                COMPREPLY=( $(compgen -W "free ,enterprise ,platinum " -- 
${value}) )
-                return 0
-                ;;
+                               case "${COMP_WORDS[COMP_OPWORD]}" in
+                                       log-set-output)
+                                               IFS=$cIFS
+                                               COMPREPLY=( $(compgen -W 
"file:,syslog:,stderr ,nil " -- ${value}) )
+                                               ;;
+                                       host-get-system-status)
+                                               IFS=$cIFS
+                                               COMPREPLY=( $(compgen -W 
"tar.bz2 ,zip " -- ${value}) )


 ( ...... 166 lines left ...... ) 

# HG changeset patch
# User Zheng Li <[email protected]>
# Date 1272953903 -3600
# Node ID 7d0fb4d42e659d81f23af7d031df8f4916efac35
# Parent  ad5ea8e64ad268ea8a99ca1bda96a962a04e348a
Add remote server support for xe's bash completion feature

According to the manual:

"... When executing commands on a remote Xen Cloud Platform host, tab completion does not normally work. However if you put the server, username, and password in an environment variable called XE_EXTRA_ARGS on the machine from which you are entering the commands, tab completion is enabled. See the section called  Basic xe syntax  for details. ..."

However, when dealing with a large number of machines, checking/updating RC file or environment variable at every single call sounds like a ugly way.

This patch adds the remote server (and other config options) support to xe's bash completion functionality. It enables tab completion when xe calls a remote server whose config can be set by command line options in "-o xxx" format or "option=xxx" format or the mix of both. The patch should work in general according to my limited tests, but please bear with my poor bash skills and feel free to improve.

A few other minor bugs were also fixed during the process.


Signed-off-by: Zheng Li <[email protected]>

diff -r ad5ea8e64ad2 -r 7d0fb4d42e65 ocaml/xe-cli/bash-completion
--- a/ocaml/xe-cli/bash-completion	Tue May 04 06:22:08 2010 +0100
+++ b/ocaml/xe-cli/bash-completion	Tue May 04 07:18:23 2010 +0100
@@ -6,24 +6,76 @@
 
 _xe()
 {
-        local IFS=$'\n,'
 
-	local cur prev opts xe IFS
+	local cur prev opts xe IFS oIFS cIFS ABORT_FLAG INGORE_FLAG SKIP_FLAG SKIP_OPTS SKIP_CONF COMP_OPWORD
+
+	oIFS=$' \t\n'
+	cIFS=$'\n,'
+
+	# The current script doesn't seem to have taken the compat mode into consideration. Using the standard 
+	# mode instead is possible but will obviously return misleading completions, while forcing to use compat 
+	# mode anyway will return message of unexpected format in most case hence become garbage. Considering the 
+	# rase usage of compat mode for interactive command (mostly as old script), we simply disable it here.
+	ABORT_FLAG=( '-help' '--help' '--compat')
+	IGNORE_FLAG=( '--debug' '--debug-on-fail' )
+	SKIP_FLAG=( '--nossl' )
+	SKIP_OPTS=( '-s' '-p' '-u' '-pw' '-pwf' '-h' )
+	ABORT_CONF=( 'compat=' )
+	IGNORE_CONF=( 'debug=' 'debugonfail=' )
+	SKIP_CONF=( 'server=' 'port=' 'username=' 'password=' 'passwordfile=' 'nossl=' )
+
+	COMP_OPWORD=-1
+	i=1
+	skip=0
+	while [ $COMP_OPWORD -lt 0 ] && [ $i -lt $COMP_CWORD ]; do
+		cont=0
+		for f in ${abort_fl...@]}; do if [[ $f == ${COMP_WORDS[i]} ]]; then return 0; fi; done
+		for f in ${ignore_fl...@]}; do if [[ $f == ${COMP_WORDS[i]} ]]; then unset COMP_WORDS[$i]; cont=1; let skip=$skip+1; break; fi; done
+		if [ $cont -gt 0 ]; then let i=$i+$cont; continue; fi
+		for f in ${skip_fl...@]}; do if [[ $f == ${COMP_WORDS[i]} ]]; then cont=1; break; fi; done
+		if [ $cont -gt 0 ]; then let i=$i+$cont; continue; fi
+		for f in ${skip_op...@]}; do if [[ $f == ${COMP_WORDS[i]} ]]; then cont=2; break; fi; done
+		if [ $cont -gt 0 ]; then let i=$i+$cont; continue; fi
+		for f in ${abort_co...@]}; do if [[ $f == ${COMP_WORDS[i]:0:${#f}} ]]; then return 0; fi; done
+		for f in ${ignore_co...@]}; do if [[ $f == ${COMP_WORDS[i]:0:${#f}} ]]; then unset COMP_WORDS[$i]; cont=1; let skip=$skip+1; break; fi; done
+		if [ $cont -gt 0 ]; then let i=$i+$cont; continue; fi
+		for f in ${skip_co...@]}; do if [[ $f == ${COMP_WORDS[i]:0:${#f}} ]]; then cont=1; break; fi; done
+		if [ $cont -gt 0 ]; then let i=$i+$cont; continue; fi
+		COMP_OPWORD=$i
+	done
+
 	COMPREPLY=()
 	cur="${COMP_WORDS[COMP_CWORD]}"
 	prev="${COMP_WORDS[COMP_CWORD-1]}"
-	xe=xe
-	
-	if [[ $COMP_CWORD == 1 ]] ; then
-	        opts=`${xe} help --minimal --all 2>/dev/null | sed -e 's/,/\ ,/g' -e 's/$/\ /g'` && COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
+
+	optargs=`echo "${abort_fl...@]} ${ignore_fl...@]} ${skip_fl...@]} ${skip_op...@]}" | sed -e 's/\ /\ ,/g'` 
+	eqargs=`echo "${abort_co...@]} ${ignore_co...@]} ${skip_co...@]}" | sed -e 's/\ /,/g'`
+	opts="$optargs ,$eqargs"
+
+
+	if [[ $COMP_OPWORD -lt 0 ]]; then
+		xe="${comp_wor...@]:0:$COMP_CWORD-$skip}"
+	else
+		xe="${comp_wor...@]:0:$COMP_OPWORD-$skip}"
+	fi
+
+	if [[ $COMP_OPWORD -lt 0 ]]; then
+		for f in ${skip_op...@]}; do if [[ $f == ${COMP_WORDS[COMP_CWORD-1]} ]]; then return 0; fi; done
+		IFS=$oIFS
+		cmdargs=`${xe} help --minimal --all 2>/dev/null | sed -e 's/,\|&/\ ,/g'`
+		IFS=$cIFS
+		opts="$opts,$cmdargs"
+		COMPREPLY=( $(compgen -W "${opts}" -X ${cur} -- ${cur}) )
+		IFS=$oIFS
 		return 0
 	fi
-	
-# parameters are passed as param=value
+
+	# parameters are passed as param=value
+
 
 	if echo ${COMP_WORDS[COMP_CWORD]} | grep "=" > /dev/null; then
 		local param value
-		local IFS=""
+		IFS=""
 		param=`echo ${COMP_WORDS[COMP_CWORD]} | cut -d= -f1`
 		value=`echo ${COMP_WORDS[COMP_CWORD]} | cut -d= -f2`
 
@@ -31,202 +83,220 @@
 		
 		case "$param" in
 			filename|file-name|license-file)
-				IFS=$'\n,'
+				IFS=$cIFS
 				COMPREPLY=( $(compgen -f ${value}) )
 				return 0
 				;;
 
 			mode) # for pif-reconfigure-ip
-				if [ "${COMP_WORDS[1]}" == "pif-reconfigure-ip" ]; then
-					IFS=$'\n,'
+				if [ "${COMP_WORDS[COMP_OPWORD]}" == "pif-reconfigure-ip" ]; then
+					IFS=$cIFS
 					COMPREPLY=( $(compgen -W "dhcp ,static ,none" -- ${value}) )
 				fi
 				return 0
 				;;
 
-		        uuid)   
-				case "${COMP_WORDS[1]}" in
+			uuid)   
+				case "${COMP_WORDS[COMP_OPWORD]}" in
 					diagnostic-vm-status) cmd=vm-list;;
 					diagnostic-vdi-status) cmd=vdi-list;;
-					*) cmd=`echo ${COMP_WORDS[1]} | awk -F- '/^host-cpu-/ || /^host-crashdump-/ { print $1 "-" $2 }
$0 !~ /^host-cpu-/ && $0 !~ /^host-crashdump-/ { print $1 }'`-list;;
+					*) cmd=`echo ${COMP_WORDS[COMP_OPWORD]} | awk -F- '/^host-cpu-/ || /^host-crashdump-/ { print $1 "-" $2 }
$0 !~ /^host-cpu-/ && $0 !~ /^host-crashdump-/ { print $1 }'`-list;;
 				esac
-                                IFS=$'\n,'
+				IFS=$cIFS
 				COMPREPLY=( $(compgen_names "$cmd" uuid "$value") )
 				return 1
 				;;
 			vm)
-                                IFS=$'\n,'
-                                COMPREPLY=( $(compgen_names vm-list name-label "$value") )
+				IFS=$cIFS
+				COMPREPLY=( $(compgen_names vm-list name-label "$value") )
 				return 0
 				;;
 
 			host)
-                                IFS=$'\n,'
+				IFS=$cIFS
 				COMPREPLY=( $(compgen_names host-list name-label "$value") )
 				return 0
 				;;
 			params)
-                                val=$(final_comma_separated_param "$value")
-				class=`echo ${COMP_WORDS[1]} | cut -d- -f1`
-				params=`${xe} ${class}-list params=all 2>/dev/null| cut -d: -f1 | sed -e s/\(.*\)//g -e s/^\ *//g -e s/\ *$//g`
-                                IFS=$'\n,'
+				val=$(final_comma_separated_param "$value")
+				class=`echo ${COMP_WORDS[COMP_OPWORD]} | cut -d- -f1`
+				IFS=$oIFS
+				params=`${xe} ${class}-list params=all 2>/dev/null | cut -d: -f1 |  sed -e s/\(.*\)//g -e s/^\ *//g -e s/\ *$//g`
+				IFS=$cIFS
 				COMPREPLY=( $(compgen -W "$params,all" -- "$val" ) )
 				return 0
 				;;
 			template)
-                                IFS=$'\n,'
-                                COMPREPLY=( $(compgen_names template-list name-label "$value") )
+				IFS=$cIFS
+				COMPREPLY=( $(compgen_names template-list name-label "$value") )
 				return 0
 				;;
 
 			# param name is used by *-param-add
 			param-name)
-				if echo ${COMP_WORDS[1]} | grep "param-add" > /dev/null; then
-					class=`echo ${COMP_WORDS[1]} | sed s/-param-add//g`
+				if echo ${COMP_WORDS[COMP_OPWORD]} | grep "param-add" > /dev/null; then
+					class=`echo ${COMP_WORDS[COMP_OPWORD]} | sed s/-param-add//g`
+					IFS=$oIFS
 					paramsset=`${xe} ${class}-list params=all 2>/dev/null | grep "SRW\|MRW" | cut -d\( -f 1 | cut -d: -f1 | sed s/\ *//` 
-					IFS=$'\n,' COMPREPLY=( $(compgen -W "${paramsset}" -- ${value}) )
+					IFS=$cIFS 
+					COMPREPLY=( $(compgen -W "${paramsset}" -- ${value}) )
 					return 0
 				fi
 				;;
 			cd-name)
-				if [[ "${COMP_WORDS[1]}" == "vm-cd-add" || "${COMP_WORDS[1]}" == "vm-cd-insert" ]]; then
-                                        IFS=$'\n,'
-                                        COMPREPLY=( $(compgen_names cd-list name-label "$value") )
+				if [[ "${COMP_WORDS[COMP_OPWORD]}" == "vm-cd-add" || "${COMP_WORDS[COMP_OPWORD]}" == "vm-cd-insert" ]]; then
+					IFS=$cIFS
+					COMPREPLY=( $(compgen_names cd-list name-label "$value") )
 					return 0
-				elif [[ "${COMP_WORDS[1]}" == "vm-cd-remove" ]]; then
-				        vm=`for i in ${comp_wor...@]:2}; do echo $i | grep "^vm="; done`
+				elif [[ "${COMP_WORDS[COMP_OPWORD]}" == "vm-cd-remove" ]]; then
+					vm=`for i in ${comp_wor...@]:2}; do echo $i | grep "^vm="; done`
+					IFS=$oIFS
 					local cds=`${xe} vm-cd-list "$vm" --minimal --multiple vbd-params=vdi-name-label vdi-params=none 2>/dev/null | sed -e "s,',$MAGIC_SQUOTE,g" -e "s,\",$MAGIC_DQUOTE,g"`
-                                        IFS=$'\n,'
-                                        COMPREPLY=( $(compgen_escape "$cds" "$value") )
+					IFS=$cIFS
+					COMPREPLY=( $(compgen_escape "$cds" "$value") )
 					return 0
 				fi
 				;;
 			on)	
-                                IFS=$'\n,'
-                                COMPREPLY=( $(compgen_names host-list name-label "$value") )
+				IFS=$cIFS
+				COMPREPLY=( $(compgen_names host-list name-label "$value") )
 				return 0
 				;;
 			key)
+				IFS=$oIFS
 				local keys=`${xe} log-get-keys --minimal 2>/dev/null`
-                                IFS=$'\n,'
-                                COMPREPLY=( $(compgen_escape "$keys" "$value") )
+				IFS=$cIFS
+				COMPREPLY=( $(compgen_escape "$keys" "$value") )
 				return 0
 				;;
 			level)
-                                IFS=$'\n,'
+				IFS=$cIFS
 				COMPREPLY=( $(compgen -W "debug ,info ,warning ,error " -- ${value}) )
 				return 0
 				;;
 			sr-name-label) # for vm-install
-                                IFS=$'\n,'
+				IFS=$cIFS
 				COMPREPLY=( $(compgen_names sr-list name-label "$value") )
 				return 0
 				;;
 			crash-dump-SR | suspend-image-SR | default-SR)
-                                IFS=$'\n,'
+				IFS=$cIFS
 				COMPREPLY=( $(compgen_names sr-list uuid "$value") )
 				return 0
 				;;
 			type) # for vbd-create/vdi-create/sr-create/sr-probe
-                                IFS=$'\n,'
-			        fst=`echo ${COMP_WORDS[1]} | cut -d- -f1`
-
+				IFS=$cIFS
+				fst=`echo ${COMP_WORDS[COMP_OPWORD]} | cut -d- -f1`
 				if [[ "${fst}" == "vbd" ]]; then
-				   COMPREPLY=( $(compgen -W "Disk ,CD " -- ${value}) )
-				   return 0
+					COMPREPLY=( $(compgen -W "Disk ,CD " -- ${value}) )
+					return 0
 				elif [[ "${fst}" == "vdi" ]]; then
-				   COMPREPLY=( $(compgen -W "system ,user ,suspend ,crashdump " -- ${value}) )
-				   return 0
+					COMPREPLY=( $(compgen -W "system ,user ,suspend ,crashdump " -- ${value}) )
+					return 0
 				elif [[ "${fst}" == "sr" ]]; then
-				   COMPREPLY=( $(compgen -W "$(xe sm-list params=type --minimal 2>/dev/null | sed 's/,/ ,/g') " -- ${value}) )
-				   return 0
+					IFS=$oIFS
+					local types=`${xe} sm-list params=type --minimal 2>/dev/null | sed 's/,\|$/ &/g'`
+					IFS=$cIFS
+					COMPREPLY=( $(compgen -W "$types" -- ${value}) )
+					return 0
 				fi
 				;;
 			entries) # for host-get-system-status
-                                val=$(final_comma_separated_param "$value")
-                                master_uuid=$(xe pool-list params=master --minimal 2>/dev/null)
-                                IFS=$'\n'
-                                caps=$($xe host-get-system-status-capabilities uuid="$master_uuid" 2>/dev/null | grep '<capability ' | sed -ne 's/.*<capability .* key="\([^"]*\)".*$/\1/p' | tr '\n' , | sed -e 's/,$//g' | tr , '\n')
-        # Fake "
-                                COMPREPLY=( $(compgen -W "$caps" -- "$val") )
-                                return 0
-                                ;;
+				val=$(final_comma_separated_param "$value")
+				IFS=$oIFS
+				master_uuid=`${xe} pool-list params=master --minimal 2>/dev/null`
+				caps=`${xe} host-get-system-status-capabilities uuid="$master_uuid" 2>/dev/null | grep '<capability ' | sed -ne 's/.*<capability .* key="\([^"]*\)".*$/\1/p' | tr '\n' , | sed -e 's/,\|$/\ &/g' | tr , '\n'`	# Fake "
+				IFS=$cIFS
+				COMPREPLY=( $(compgen -W "$caps" -- "$val") )
+				return 0
+				;;
 			output)
-                                case "${COMP_WORDS[1]}" in
-                                    log-set-output)
-                                        IFS=$'\n,'
-                                        COMPREPLY=( $(compgen -W "file,syslog,nil " -- ${value}) )
-                                        ;;
-                                    host-get-system-status)
-                                        IFS=$'\n,'
-                                        COMPREPLY=( $(compgen -W "tar.bz2 ,zip " -- ${value}) )
-                                        ;;
-                                esac
-                                return 0
-                                ;;
-            copy-bios-strings-from) # for vm-install
-                COMPREPLY=`${xe} host-list params=uuid --minimal 2>/dev/null`
-                return 0
-                ;;
-            edition) # for host-apply-edition (licensing)
-                IFS=$'\n,'
-                COMPREPLY=( $(compgen -W "free ,enterprise ,platinum " -- ${value}) )
-                return 0
-                ;;
+				case "${COMP_WORDS[COMP_OPWORD]}" in
+					log-set-output)
+						IFS=$cIFS
+						COMPREPLY=( $(compgen -W "file:,syslog:,stderr ,nil " -- ${value}) )
+						;;
+					host-get-system-status)
+						IFS=$cIFS
+						COMPREPLY=( $(compgen -W "tar.bz2 ,zip " -- ${value}) )
+						;;
+				esac
+				return 0
+				;;
+			copy-bios-strings-from) # for vm-install
+				IFS=$oIFS
+				hosts=`${xe} host-list params=uuid --minimal 2>/dev/null | sed 's/,\|$/\ &/g'`
+				IFS=$cIFS
+				COMPREPLY=( $(compgen -W "$hosts" -- ${value}) )
+				return 0
+				;;
+			edition) # for host-apply-edition (licensing)
+				IFS=$cIFS
+				COMPREPLY=( $(compgen -W "free ,advanced ,enterprise ,enterprise-xd ,platinum " -- ${value}) )
+				return 0
+				;;
 			*)
 				snd=`echo ${param} | cut -d- -f2`
 				fst=`echo ${param} | cut -d- -f1`
 				
 				if [[ "${snd}" == "uuid" ]]; then
-				   if [[ "${fst}" == "snapshot" ]]; then
-				   	  all=""
-				   else
-					  all="--all"
-				   fi
-				   uuids=`${xe} ${fst}-list ${all} params=uuid --minimal 2>/dev/null`
-                                   IFS=$'\n,'
-                                   COMPREPLY=( $(compgen_escape "$uuids" "$value") )
-				   return 0
+					if [[ "${fst}" == "snapshot" ]]; then
+						all=""
+					else
+						all="--all"
+					fi
+					IFS=$oIFS
+					uuids=`${xe} ${fst}-list ${all} params=uuid --minimal 2>/dev/null`
+					IFS=$cIFS
+					COMPREPLY=( $(compgen_escape "$uuids" "$value") )
+					return 0
 				else
-				   fst=`echo ${COMP_WORDS[1]} | cut -d- -f1`
-				   snd=`echo ${COMP_WORDS[1]} | cut -d- -f2`
-				   if [[ "${snd}" == "list" || "${fst}" == "vm" ]]; then
-                                     IFS=$'\n,'
-				     COMPREPLY=( $(compgen_names "${fst}-list" "$param" "$value") )
-				     return 0
-				   fi
-				fi	  
+					fst=`echo ${COMP_WORDS[COMP_OPWORD]} | cut -d- -f1`
+					snd=`echo ${COMP_WORDS[COMP_OPWORD]} | cut -d- -f2`
+					if [[ "${snd}" == "list" || "${fst}" == "vm" ]]; then
+						IFS=$cIFS
+						COMPREPLY=( $(compgen_names "${fst}-list" "$param" "$value") )
+						return 0
+					fi
+				fi
 				;;
 		esac
 	else
 		local param reqd
 		param=${COMP_WORDS[COMP_CWORD]}
-		vmselectors=`${xe} help ${COMP_WORDS[1]} 2>/dev/null | grep "optional params" | grep "<vm-selectors>"`
-		hostselectors=`${xe} help ${COMP_WORDS[1]} 2>/dev/null | grep "optional params" | grep "<host-selectors>"`
 		isdeviceconfig=`echo "${param}" | grep "device-config:"`
 		isvcpusparams=`echo "${param}" | grep "VCPUs-params:"`
+		IFS=$oIFS
+		vmselectors=`${xe} help ${COMP_WORDS[$COMP_OPWORD]} 2>/dev/null | grep "optional params" | grep "<vm-selectors>"`
+		hostselectors=`${xe} help ${COMP_WORDS[$COMP_OPWORD]} 2>/dev/null | grep "optional params" | grep "<host-selectors>"`
+		IFS=$cIFS
 		if [ "${isdeviceconfig}" ]; then
-			IFS=" " type=$(for i in ${comp_wor...@]:2}; do echo $i | grep "^type="; done | sed -e 's/^type=//' | tr [A-Z] [a-z])
-			extraargs=,$(IFS=";"; for i in `xe sm-list type=${type} params=configuration --minimal 2>/dev/null`; do echo device-config:$i | cut -d ':' -f 1-2; done | sed -e 's/ //g' -e 's/$/=/')
+			IFS=" " 
+			type=$(for i in ${comp_wor...@]:$COMP_OPWORD+1}; do echo $i | grep "^type="; done | sed -e 's/^type=//' | tr [A-Z] [a-z])
+			IFS=$oIFS
+			devparam=`${xe} sm-list type=${type} params=configuration --minimal`
+			IFS=";"
+			extraargs=,$(for i in $devparam; do echo device-config:$i | cut -d ':' -f 1-2; done | sed -e 's/ //g' -e 's/$/=/')
 		elif [ "${isvcpusparams}" ]; then
+			IFS=";"
 			extraargs=,$(for i in weight cap mask; do echo "VCPUs-params:$i="; done)
 		elif [ "${vmselectors}" ]; then
-		   if [ "${param}" ] ; then
-		      extraargs=",vm=,"$(params "vm-list" | sed 's/params=//g')
-		   else
-		      extraargs=",vm="
-		   fi
+			if [ "${param}" ] ; then
+				extraargs=",vm=,"$(params "vm-list" | sed 's/params=//g')
+			else
+				extraargs=",vm="
+			fi
 		elif [ "${hostselectors}" ]; then
-		   if [ "${param}" ] ; then
-		      extraargs=",host=,"$(params "host-list" | sed 's/params=//g')
-		   else
-		      extraargs=",host="
-		   fi
+			if [ "${param}" ] ; then
+				extraargs=",host=,"$(params "host-list" | sed 's/params=//g')
+			else
+				extraargs=",host="
+			fi
 		else
-   		   extraargs=""
+			extraargs=""
 		fi
-                IFS=$'\n,'
-		COMPREPLY=( $(compgen_params "${COMP_WORDS[1]}" "$extraargs" "$param") )
+		IFS=$cIFS
+		COMPREPLY=( $(compgen_params "${COMP_WORDS[COMP_OPWORD]}" "$extraargs" "$param") )
 		return 0
 	fi
 }
@@ -236,22 +306,25 @@
 #
 final_comma_separated_param()
 {
+  local IFS
   if expr "$1" : ".*," >/dev/null
   then
-      old_ifs="$IFS"
-      bits=$(echo "$1" | sed -e 's#^\(.*\),\([^,]*\)$#\1%\2#g')
-      IFS=%
-      bits=($bits)
-      echo "${bits[1]}"
-      IFS="$old_ifs"
+    old_ifs="$IFS"
+    bits=$(echo "$1" | sed -e 's#^\(.*\),\([^,]*\)$#\1%\2#g')
+    IFS=%
+    bits=($bits)
+    echo "${bits[1]}"
+    IFS="$old_ifs"
   else
-      echo "$1"
+    echo "$1"
   fi
 }
 
 compgen_names()
 {
-  local vals=$("$xe" "$1" --minimal params="$2" 2>/dev/null | sed -e "s,',$MAGIC_SQUOTE,g" -e "s,\",$MAGIC_DQUOTE,g")
+  local IFS=$oIFS
+  local vals=`${xe} "$1" --minimal params="$2" 2>/dev/null | sed -e "s,',$MAGIC_SQUOTE,g" -e "s,\",$MAGIC_DQUOTE,g"`
+  local IFS=$cIFS
   compgen_escape "$vals" "$3"
 }
 
@@ -263,11 +336,14 @@
 
 params()
 {
-    "$xe" help "$1" 2>/dev/null | grep '^[^:]*params' | cut -d: -f2- | egrep -v "^ $" | cut -c 2- | sed -e 's/,/=,/g' -e 's/$/=/g' -e 's/:=/:/g' -e 's/-=/-/g' -e 's/ //g'
+  local IFS=$oIFS
+  ${xe} help "$1" | grep '^[^:]*params' | cut -d: -f2- | egrep -v "^ $" | cut -c 2- | sed -e 's/,/=,/g' -e 's/$/=/g' -e 's/:=/:/g' -e 's/-=/-/g' -e 's/ //g'
+  local IFS=$cIFS
 }
 
 compgen_params()
 {
+  local IFS=$cIFS
   local v=$(params "$1" | sed -e 's/<vm-selectors>=//g' -e 's/<host-selectors>=//g')
   compgen -o nospace -W "$v$2" -- "$3"
 }
_______________________________________________
xen-api mailing list
[email protected]
http://lists.xensource.com/mailman/listinfo/xen-api

Reply via email to