[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-API] [PATCH] Add remote server support for xe's bash completion feature


  • To: xen-api@xxxxxxxxxxxxxxxxxxx
  • From: Zheng Li <dev@xxxxxxxx>
  • Date: Tue, 04 May 2010 06:27:27 -0000
  • Delivery-date: Mon, 03 May 2010 19:10:11 -0700
  • List-id: Discussion of API issues surrounding Xen <xen-api.lists.xensource.com>

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 <dev@xxxxxxxx>


 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_FLAG[@]}; do if [[ $f == ${COMP_WORDS[i]} ]]; 
then return 0; fi; done
+               for f in ${IGNORE_FLAG[@]}; 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_FLAG[@]}; 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_OPTS[@]}; 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_CONF[@]}; do if [[ $f == 
${COMP_WORDS[i]:0:${#f}} ]]; then return 0; fi; done
+               for f in ${IGNORE_CONF[@]}; 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_CONF[@]}; 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_FLAG[@]} ${IGNORE_FLAG[@]} ${SKIP_FLAG[@]} 
${SKIP_OPTS[@]}" | sed -e 's/\ /\ ,/g'` 
+       eqargs=`echo "${ABORT_CONF[@]} ${IGNORE_CONF[@]} ${SKIP_CONF[@]}" | sed 
-e 's/\ /,/g'`
+       opts="$optargs ,$eqargs"
+
+
+       if [[ $COMP_OPWORD -lt 0 ]]; then
+               xe="${COMP_WORDS[@]:0:$COMP_CWORD-$skip}"
+       else
+               xe="${COMP_WORDS[@]:0:$COMP_OPWORD-$skip}"
+       fi
+
+       if [[ $COMP_OPWORD -lt 0 ]]; then
+               for f in ${SKIP_OPTS[@]}; 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_WORDS[@]:2}; do 
echo $i | grep "^vm="; done`
+                               elif [[ "${COMP_WORDS[COMP_OPWORD]}" == 
"vm-cd-remove" ]]; then
+                                       vm=`for i in ${COMP_WORDS[@]: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 ...... ) 

Attachment: xen-api.patch
Description: Text Data

_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.