Files
vboxmanage-bash-completion/VBoxManage
2015-04-09 19:49:50 +02:00

827 lines
28 KiB
Bash

# bash command-line completion for virtualbox
#
# This version of bash completion was born due to the need of fast and easy
# access to the maze of commands and parameters VBoxManage provides. Based on
# Sebastian[1] script I've managed to improve it and adapt to newest stable
# version available in Gentoo Portage.
#
# [1] Sebastian T. Hafner <sonix@own-hero.net>
#
#
# [x] adoptstate
# [x] bandwidthctl
# [x] clonehd
# [x] clonevm
# [x] closemedium
# [x] controlvm
# [x] convertfromraw
# [x] createhd
# [ ] createvm
# [ ] debugvm
# [ ] dhcpserver
# [ ] discardstate
# [ ] export
# [ ] extpack
# [ ] getextradata
# [ ] guestcontrol
# [ ] guestproperty
# [ ] hostonlyif
# [ ] import
# [x] list
# [ ] metrics
# [ ] modifyhd
# [ ] modifyvm - a LOT options missing
# [ ] natnetwork
# [ ] registervm
# [ ] setextradata
# [ ] setproperty
# [ ] sharedfolder
# [x] showhdinfo
# [x] showvminfo
# [x] snapshot
# [x] startvm
# [x] storageattach
# [x] storagectl
# [x] unregistervm
# [x] usbfilter
_VBoxManage() {
local cur prev opts cmd subcommand tmp items name index result
# Generate registered hard disk files.
# NOTE: This function may introduce some quirks, if there is a space or
# other characters which usually are treated as IFS - like space. Pipe
# character used in disk filename will ruin this completions.
_hdd_comp() {
local cur=$1
local hdds
local item
hdds=$(VBoxManage list hdds | \
grep -A 1 'normal (base)' | \
grep "Location:" | \
sed 's/Location:\s\+//' | \
sed 's/\s/\\ /g' | \
tr '\n' '|' | \
sed 's/|$//')
IFS='|' read -ra hdds <<< "$hdds"
for item in "${hdds[@]}"
do
[[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item")
done
}
_floppy_comp() {
local cur=$1
local floppies
local item
floppies=$(VBoxManage list floppies | \
grep "Location:" | \
sed 's/Location:\s\+//' | \
sed 's/\s/\\ /g' | \
tr '\n' '|' | \
sed 's/|$//')
IFS='|' read -ra floppies <<< "$floppies"
for item in "${floppies[@]}"
do
[[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item")
done
}
_dvds_comp() {
local cur=$1
local dvds
local item
dvds=$(VBoxManage list dvds | \
grep "Location:" | \
sed 's/Location:\s\+//' | \
sed 's/\s/\\ /g' | \
tr '\n' '|' | \
sed 's/|$//')
IFS='|' read -ra dvds <<< "$dvds"
for item in "${dvds[@]}"
do
[[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item")
done
}
# Complete registered VM names.
# Issues are the same as in above function.
_vms_comp() {
local command=$1
local cur=$2
local vms
local item
compopt -o filenames
vms=$(VBoxManage list $command | \
awk -F ' {' '{ print $1 }' | \
tr '\n' '|' | \
sed 's/|$//' | \
sed 's/"//g')
IFS='|' read -ra vms <<< "$vms"
for item in "${vms[@]}"
do
[[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item")
done
}
_list_comp() {
local cur=$1
local list
list=$(VBoxManage list | \
grep '|' | \
sed 's/\[.*\]//g'| \
sed 's/VBoxManage list//' | \
tr "\\n" " " | \
sed 's/$/\n/' | \
sed 's/\s\+//g' | \
sed 's/|/ /g')
COMPREPLY=( $(compgen -W "$list" -- ${cur}) )
}
_group_comp() {
local cur=$1
local list
local item
list=$(VBoxManage list groups | \
tr '\n' '|' | \
sed 's/|$//' | \
sed 's/\s/\\ /g'| \
sed 's/"//g')
IFS='|' read -ra list <<< "$list"
for item in "${list[@]}"
do
[[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item")
done
}
# Check the COMP_WORDS looking for name of the vm. If name contain space or
# is enclosed in quotes, glue name together in variable name. Variable index
# will hold the last index of COMP_WORDS array which contain the end of the
# name.
_find_item_name() {
local idx=$1
name=""
while true
do
name="${NAME}${COMP_WORDS[$idx]}"
[[ ${COMP_WORDS[$idx]} = *'"' ]] && break
if [[ ${COMP_WORDS[$idx]} = '"'* || ${COMP_WORDS[$idx]} = *'\ ' ]]
then
idx=$((++idx))
continue
fi
break
done
index=$idx
}
_get_excluded_items() {
local i
result=""
for i in $@; do
[[ " ${COMP_WORDS[@]} " == *" $i "* ]] && continue
result="$result $i"
done
}
_bandwidthctl_comp() {
local rules cur=$1
local item
_find_item_name 2
rules=$(VBoxManage bandwidthctl "${name//\\/}" \
list --machinereadable | \
awk -F ',' '{print $1}' | \
awk -F '=' '{print $2}' | \
tr '\n' '|' | \
sed 's/|$//' | \
sed 's/\s/\\ /g')
IFS='|' read -ra rules <<< "$rules"
for item in "${rules[@]}"
do
[[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item")
done
}
_snapshot_comp() {
local snap cur=$1
local item
_find_item_name 2
snap=$(VBoxManage snapshot "${name//\\/}" \
list | \
grep UUID |
awk -F ': ' '{print $2}' | \
sed 's/ (.*//' | \
tr '\n' '|' | \
sed 's/|$//' | \
sed 's/\s/\\ /g')
IFS='|' read -ra snap <<< "$snap"
for item in "${snap[@]}"
do
[[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item")
done
}
_webcam_comp() {
local devs cur=$1
local item
_find_item_name 2
devs=$(VBoxManage controlvm "${name//\\/}" \
webcam list | \
tr '\n' ' ' | \
sed 's/|s$//')
read -ra devs <<< "$devs"
for item in "${devs[@]}"
do
[[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item")
done
}
_webcam_avail_comp() {
local devs cur=$1
local item
_find_item_name 2
devs=$(VBoxManage list webcams | \
grep dev | \
tr '\n' ' ' | \
sed 's/|s$//')
read -ra devs <<< "$devs"
for item in "${devs[@]}"
do
[[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item")
done
}
_list_comp() {
local list
list=$(VBoxManage list | \
grep '|' | \
sed 's/\[.*\]//g'| \
sed 's/VBoxManage list//' | \
tr "\\n" " " | \
sed 's/$/\n/' | \
sed 's/\s\+//g' | \
sed 's/|/ /g')
COMPREPLY=( $(compgen -W "$list" -- ${cur}) )
}
COMP_WORDBREAKS=${COMP_WORDBREAKS//|/} # remove pipe from comp word breaks
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
lastbutone="${COMP_WORDS[COMP_CWORD-2]}"
if [[ COMP_CWORD -ge 2 ]]; then
cmd="${COMP_WORDS[1]}"
if [[ $cmd == "-q" ]]; then
cmd="${COMP_WORDS[2]}"
fi
fi
# all possible commands for the VBoxManage
opts=$(VBoxManage -q help | \
egrep -o "^\s\s[a-z]+ " | \
grep -v VBoxManage | \
awk '{print $1}'| \
sort | \
uniq)
if [[ ${cur} == "-q" || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
case "${cmd}" in
adoptstate)
_vms_comp vms ${cur}
;;
bandwidthctl)
local items=(add set remove list)
if [[ ${prev} == ${cmd} ]]; then
_vms_comp vms ${cur}
else
_find_item_name 2
subcommand=${COMP_WORDS[$((index+1))]}
if [[ " ${items[@]} " == *" $subcommand "* ]]; then
case "${subcommand}" in
add)
items=(--type --limit)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
;;
set)
if [[ ${prev} == "set" ]]; then
_bandwidthctl_comp ${cur}
else
[[ " ${COMP_WORDS[@]} " != *" --limit "* ]] && \
COMPREPLY=( $(compgen -W "--limit" -- \
${cur}) )
fi
;;
remove)
if [[ ${prev} == "remove" ]]; then
_bandwidthctl_comp ${cur}
fi
;;
list)
if [[ ${prev} == "list" ]]; then
COMPREPLY=( $(compgen -W "--machinereadable" \
-- ${cur}) )
fi
;;
esac
case "${prev}" in
--type)
COMPREPLY=( $(compgen -W "disk network" -- ${cur}) )
;;
esac
else
[[ ${#COMPREPLY[@]} -eq 0 ]] && \
COMPREPLY=( $(compgen -W "${items[*]}" -- ${cur}) )
fi
fi
;;
clonehd)
if [[ ${prev} == ${cmd} ]]; then
_hdd_comp ${cur}
else
_find_item_name 2
items=(--format --variant --existing)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
case "${prev}" in
--format)
COMPREPLY=( $(compgen -W "VDI VMDK VHD RAW" -- ${cur}) )
;;
--variant)
COMPREPLY=( $(compgen -W "Standard Fixed Split2G Stream
ESX" -- ${cur}) )
;;
esac
fi
;;
clonevm)
if [[ ${prev} == ${cmd} ]]; then
_vms_comp vms ${cur}
else
_find_item_name 2
items=(--snapshot --mode --options --name --groups --basefolder
--uuid --register)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
case "${prev}" in
--snapshot)
COMPREPLY=()
_snapshot_comp ${cur}
;;
--mode)
COMPREPLY=( $(compgen -W "machine machineandchildren
all" -- ${cur}) )
;;
--options)
COMPREPLY=( $(compgen -W "link keepallmacs keepnatmacs
keepdisknames" -- ${cur}) )
;;
--groups)
COMPREPLY=()
_group_comp ${cur}
;;
--basefolder)
COMPREPLY=( $(compgen -o dirnames -- ${cur}) )
;;
esac
fi
;;
closemedium)
if [[ ${prev} == ${cmd} ]]; then
COMPREPLY=( $(compgen -W "disk dvd floppy" -- ${cur}) )
else
case "${prev}" in
disk)
_hdd_comp ${cur}
;;
dvd)
_dvds_comp ${cur}
;;
floppy)
_floppy_comp ${cur}
;;
*)
items=(--delete)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
;;
esac
fi
;;
controlvm)
if [[ ${prev} == ${cmd} ]]; then
_vms_comp runningvms ${cur}
else
local items=(acpipowerbutton acpisleepbutton clipboard
cpuexecutioncap draganddrop guestmemoryballoon
keyboardputscancode natpf1 nic1 nicpromisc1 nicproperty1
nictrace1 nictracefile1 natpf2 nic2 nicpromisc2 nicproperty2
nictrace2 nictracefile2 natpf3 nic3 nicpromisc3 nicproperty3
nictrace3 nictracefile3 natpf4 nic4 nicpromisc4 nicproperty4
nictrace4 nictracefile4 natpf5 nic5 nicpromisc5 nicproperty5
nictrace5 nictracefile5 natpf6 nic6 nicpromisc6 nicproperty6
nictrace6 nictracefile6 natpf7 nic7 nicpromisc7 nicproperty7
nictrace7 nictracefile7 natpf8 nic8 nicpromisc8 nicproperty8
nictrace8 pause plugcpu poweroff reset resume savestate
screenshotpng setcredentials setlinkstate1 setlinkstate2
setlinkstate3 setlinkstate4 setlinkstate5 setlinkstate6
setlinkstate7 setlinkstate8 setvideomodehint teleport unplugcpu
usbattach usbdetach vcpenabled vcpscreens vrde vrdeport
vrdeproperty vrdevideochannelquality webcam)
_find_item_name 2
subcommand=${COMP_WORDS[$((index+1))]}
if [[ " ${items[@]} " == *" $subcommand "* ]]; then
case "${subcommand}" in
nictracefile[1-8])
[[ ${prev} == "nictracefile"* ]] && \
COMPREPLY=( $(compgen -f -- ${cur}) )
;;
nictrace[1-8])
[[ ${prev} == "nictrace"* ]] && \
COMPREPLY=( $(compgen -W "on off" -- ${cur}) )
;;
nicpromisc[1-8])
[[ ${prev} == "nicpromisc"* ]] && \
COMPREPLY=( $(compgen -W "deny allow-vms
allow-all" -- ${cur}) )
;;
nic[1-8])
[[ ${prev} == "nic"* ]] && \
COMPREPLY=( $(compgen -W "null nat bridged intnet
hostonly generic natnetwork" -- ${cur}) )
;;
natpf[1-8])
[[ ${prev} == "natpf"* ]] && \
COMPREPLY=( $(compgen -W "delete tcp
udp" -- ${cur}) )
;;
setlinkstate[1-8])
[[ ${prev} == "setlinkstate"* ]] && \
COMPREPLY=( $(compgen -W "on off" -- ${cur}) )
;;
clipboard)
[[ ${prev} == "clipboard" ]] && \
COMPREPLY=( $(compgen -W "disabled hosttoguest
guesttohost bidirectional" -- ${cur}) )
;;
draganddrop)
[[ ${prev} == "draganddrop" ]] && \
COMPREPLY=( $(compgen -W "disabled
hosttoguest" -- ${cur}) )
;;
vrde|vcpenabled)
[[ ${prev} == "vrde" ||
${prev} == "vcpenabled" ]] && \
COMPREPLY=( $(compgen -W "on off" -- ${cur}) )
;;
vcpscreens)
[[ ${prev} == "vcpscreens" ]] && \
COMPREPLY=( $(compgen -W "all none" -- ${cur}) )
;;
setcredentials)
tmp=(--passwordfile --allowlocallogon)
_get_excluded_items "${tmp[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
;;
teleport)
tmp=(--host --port --maxdowntime --passwordfile
--password)
_get_excluded_items "${tmp[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
;;
webcam)
[[ ${prev} == "webcam" ]] && \
COMPREPLY=( $(compgen -W "attach detach
list" -- ${cur}) )
[[ ${prev} == "detach" ]] && \
_webcam_comp ${cur}
[[ ${prev} == "attach" ]] && \
_webcam_avail_comp ${cur}
;;
esac
else
[[ ${#COMPREPLY[@]} -eq 0 ]] && \
COMPREPLY=( $(compgen -W "${items[*]}" -- ${cur}) )
fi
fi
;;
convertfromraw)
local items=(--format --variant --uuid)
if [[ ${prev} == ${cmd} ]]; then
COMPREPLY=( $(compgen -W "${items[*]}" -- ${cur}) )
else
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
case "${prev}" in
--format)
COMPREPLY=( $(compgen -W "VDI VMDK VHD" -- ${cur}) )
;;
--variant)
COMPREPLY=( $(compgen -W "Standard Fixed Split2G Stream
ESX" -- ${cur}) )
;;
esac
fi
;;
createhd)
items=(--filename --size --sizebyte --diffparent --format --variant)
if [[ ${prev} == ${cmd} ]]; then
COMPREPLY=( $(compgen -W "${items[*]}" -- ${cur}) )
else
[[ " ${COMP_WORDS[@]} " == *" --size "* ||
" ${COMP_WORDS[@]} " == *" --sizebyte "* ]] &&
items=(--filename --diffparent --format --variant)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
case "${prev}" in
--filename)
COMPREPLY=( $(compgen -- ${cur}) )
;;
--diffparent)
COMPREPLY=()
_hdd_comp ${cur}
;;
--format)
COMPREPLY=( $(compgen -W "VDI VMDK VHD" -- ${cur}) )
;;
--variant)
COMPREPLY=( $(compgen -W "Standard Fixed Split2G Stream
ESX" -- ${cur}) )
;;
esac
fi
;;
createvm)
;;
debugvm)
;;
dhcpserver)
;;
discardstate)
;;
"export")
;;
extpack)
;;
getextradata)
;;
guestcontrol)
;;
guestproperty)
;;
hostonlyif)
;;
import)
;;
list)
if [[ ${prev} == ${cmd} ]]; then
_list_comp ${cur}
else
case "${prev}" in
--long|-l)
COMPREPLY=()
;;
*)
COMPREPLY=( $(compgen -W "-l --long" -- ${cur}) )
;;
esac
fi
;;
metrics)
;;
modifyhd)
;;
modifyvm)
;;
natnetwork)
;;
registervm)
;;
setextradata)
;;
setproperty)
;;
sharedfolder)
;;
showhdinfo)
_hdd_comp ${cur}
;;
showvminfo)
if [[ ${prev} == ${cmd} ]]; then
_vms_comp vms ${cur}
else
if [[ " ${COMP_WORDS[@]} " == *" --log "* ]]; then
COMPREPLY=()
elif [[ " ${COMP_WORDS[@]} " == *" --details "* ||
" ${COMP_WORDS[@]} " == *" --machinereadable "* ]]; then
local items=(--details --machinereadable)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
else
local items=(--details --machinereadable --log)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
fi
fi
;;
snapshot)
items=(take delete restore restorecurrent edit list showvminfo)
if [[ ${prev} == ${cmd} ]]; then
_vms_comp vms ${cur}
else
_find_item_name 2
subcommand=${COMP_WORDS[$((index+1))]}
if [[ " ${items[@]} " == *" $subcommand "* ]]; then
case "${subcommand}" in
take)
items=(--description --live)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
;;
delete|restore|showvminfo)
_snapshot_comp ${cur}
;;
restorecurrent)
COMPREPLY=()
;;
edit)
if [[ ${prev} == "edit" &&
${#COMP_WORDS[@]} == 5 ]]; then
_snapshot_comp ${cur}
COMPREPLY+=("--current")
else
items=(--name --description)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
fi
;;
list)
items=(--details --machinereadable)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
;;
esac
else
[[ ${#COMPREPLY[@]} -eq 0 ]] && \
COMPREPLY=( $(compgen -W "${items[*]}" -- ${cur}) )
fi
fi
;;
startvm)
if [[ ${prev} == ${cmd} ]]; then
_vms_comp vms ${cur}
elif [[ "${prev}" == "--type" ]]; then
COMPREPLY=( $(compgen -W "gui sdl headless" -- ${cur}) )
else
local items=(--type)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
fi
;;
storageattach)
if [[ ${prev} == ${cmd} ]]; then
_vms_comp vms ${cur}
else
_find_item_name 2
local items=(--storagectl --port --device --type --medium --mtype
--comment --setuuid --setparentuuid --passthrough --tempeject
--nonrotational --discard --bandwidthgroup --forceunmount
--server --target --tport --lun --encodedlun --username
--password --initiator --intnet)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
case "${prev}" in
--type)
COMPREPLY=( $(compgen -W "dvddrive hdd fdd" -- ${cur}) )
;;
--medium)
COMPREPLY=()
local tmp=(none emptydrive additions)
_hdd_comp ${cur}
_floppy_comp ${cur}
_dvds_comp ${cur}
for item in "${tmp[@]}"
do
[[ ${item^^} == ${cur^^}* ]] && COMPREPLY+=("$item")
done
;;
--mtype)
COMPREPLY=( $(compgen -W "normal writethrough immutable
shareable readonly multiattach" -- ${cur}) )
;;
--passthrough|--tempeject|--nonrotational|--discard)
COMPREPLY=( $(compgen -W "on off" -- ${cur}) )
;;
esac
fi
;;
storagectl)
local items=(--name --add --controller --portcount --hostiocache
--bootable --remove)
if [[ ${prev} == ${cmd} ]]; then
_vms_comp vms ${cur}
else
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
case "${prev}" in
--add)
COMPREPLY=( $(compgen -W "ide sata scsi floppy
sas" -- ${cur}) )
;;
--controller)
COMPREPLY=( $(compgen -W "LSILogic LSILogicSAS BusLogic
IntelAHCI PIIX3 PIIX4 ICH6 I82078" -- ${cur}) )
;;
--bootable|--hostiocache)
COMPREPLY=( $(compgen -W "on off" -- ${cur}) )
;;
esac
fi
;;
unregistervm)
if [[ ${prev} == ${cmd} ]]; then
_vms_comp vms ${cur}
else
local items=(--delete)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
fi
;;
usbfilter)
if [[ COMP_CWORD -ge 3 ]]; then
subcommand="${COMP_WORDS[2]}"
if [[ $subcommand == "${cmd}" ]]; then
subcommand="${COMP_WORDS[3]}"
fi
fi
if [[ ${prev} == ${cmd} ]]; then
COMPREPLY=( $(compgen -W "add modify remove" -- ${cur}) )
else
case "${prev}" in
--target)
_vms_comp vms ${cur}
COMPREPLY+=( $(compgen -W "global" -- ${cur}) )
;;
--action)
COMPREPLY=( $(compgen -W "ignore hold" -- ${cur}) )
;;
--active|--remote)
COMPREPLY=( $(compgen -W "yes no" -- ${cur}) )
;;
esac
if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
case "${subcommand}" in
add|modify)
local items=(--target --name --action --active
--vendorid --productid --revision --manufacturer
--product --remote --serialnumber --maskedinterfaces)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
;;
remove)
local items=(--target)
_get_excluded_items "${items[@]}"
COMPREPLY=( $(compgen -W "$result" -- ${cur}) )
;;
esac
fi
fi
;;
esac
}
complete -o default -F _VBoxManage VBoxManage
# vim: set ft=sh tw=80 sw=4 et :