1 # bash completion for jailhouse
3 # Copyright (c) Benjamin Block, 2014
4 # Copyright (c) Siemens AG, 2015
7 # Benjamin Block <bebl@mageta.org>
8 # Jan Kiszka <jan.kiszka@siemens.com>
10 # This work is licensed under the terms of the GNU GPL, version 2. See
11 # the COPYING file in the top-level directory.
14 # usage: - include the directory containing the `jailhouse`-tool into your
16 # - source this tile `. tools/jailhouse_bashcompletion`
17 # - alternatively you can but this file into your distributions
18 # bash-completion directory
20 # there is a broad variety of places where distris may put this:
21 # - /usr/share/bash-completion/
22 # - /etc/bash_completion.d/
23 # - $BASH_COMPLETION_COMPAT_DIR
24 # - $BASH_COMPLETION_DIR
27 # dependencies: - bash-completion (>= 1.3) package installed and activated in
30 # bash-completion websites:
31 # - http://bash-completion.alioth.debian.org/
32 # - https://wiki.debian.org/Teams/BashCompletion
33 # - http://anonscm.debian.org/cgit/bash-completion/bash-completion.git/
35 # only if jailhouse is in ${PATH}
36 ( which jailhouse &>/dev/null ) && \
39 # test for the required helper-functions
40 if ! type _filedir &>/dev/null; then
41 # functions not defined
43 # The distributions seem to handle the inclusion of these function in a
44 # broad variety of ways. To keep this script as simple as possible we
45 # depend on this to work.
50 function _jailhouse_get_id() {
51 local names ids cur prev quoted quoted_cur toks
59 _quote_readline_by_ref "$cur" quoted_cur
61 # handle the '{ ID | [--name] NAME }' part of cell-calls
63 # if we are at position 3 of the commnadline we can either input a
64 # concrete `ID`/`NAME` or the option `--name`
65 if [ "${COMP_CWORD}" -eq 3 ]; then
67 # get possible ids and names
68 if [ -d /sys/devices/jailhouse/cells ]; then
69 for i in /sys/devices/jailhouse/cells/*/id; do
70 ids="${ids} $(cat "${i}" | tr '\n' ' ')"
72 for n in /sys/devices/jailhouse/cells/*; do
73 _quote_readline_by_ref "${n##*/}" quoted
74 names="${names} ${quoted}"
78 COMPREPLY=( $( compgen -W "--name ${ids} ${names}" -- \
81 # if we are already at position 4, may enter a `NAME`, if `--name` was
83 elif [ "${COMP_CWORD}" -eq 4 ]; then
84 [ "${prev}" = "--name" ] || return 1
87 if [ -d /sys/devices/jailhouse/cells ]; then
88 for n in /sys/devices/jailhouse/cells/*; do
89 _quote_readline_by_ref "${n##*/}" quoted
90 names="${names} ${quoted}"
94 COMPREPLY=( $( compgen -W "${names}" -- ${quoted_cur} ) )
96 # the id or name is only accepted at position 3 or 4
104 function _jailhouse_cell_linux() {
107 cur="${COMP_WORDS[COMP_CWORD]}"
108 prev="${COMP_WORDS[COMP_CWORD-1]}"
110 options="-h --help -i --initrd -c --cmdline -w --write-params"
112 # if we already have begun to write an option
113 if [[ "$cur" == -* ]]; then
114 COMPREPLY=( $( compgen -W "${options}" -- "${cur}") )
116 # if the previous was on of the following options
118 -i|--initrd|-w|--write-params)
119 # search an existing file
124 # we can't really predict this
129 # neither option, nor followup of one. Lets assume we want
130 # the cell or the kernel
131 for n in `seq ${COMP_CWORD-1}`; do
132 word="${COMP_WORDS[n]}"
133 if [[ "${word}" == *.cell ]] && ( [ $n -eq 1 ] ||
134 [[ "${COMP_WORDS[n-1]}" != -* ]] ); then
135 # we already have a cell, this is the kernel
146 function _jailhouse_cell() {
147 local cur prev quoted_cur
149 cur="${COMP_WORDS[COMP_CWORD]}"
150 prev="${COMP_WORDS[COMP_CWORD-1]}"
152 _quote_readline_by_ref "$cur" quoted_cur
154 # handle subcommand of the cell-command
157 # search for guest-cell configs
159 # this command takes only a argument at place 3
160 [ "${COMP_CWORD}" -gt 3 ] && return 1
165 # first, select the id/name of the cell we want to load a image
167 _jailhouse_get_id "${cur}" "${prev}" && return 0
169 # [image & address] can be repeated
171 # after id/name insert image-file (always true)
172 if [ "${COMP_CWORD}" -eq 4 ] || ( [ "${COMP_CWORD}" -eq 5 ] && \
173 [ "${COMP_WORDS[3]}" = "--name" ] ); then
179 # the first image has to be placed, after that it is:
181 # [image [<-a|--address> <address>]
182 # [image [<-a|--address> <address>] ... ]]
184 # prev was an addresse, no image here
185 if [[ "${prev}" = "-a" || "${prev}" = "--address" ]]; then
188 # prev was either an image or a address-number
190 # did we already start to type an other switch
191 if [[ "$cur" == -* ]]; then
192 COMPREPLY=( $( compgen -W "-a --address" -- \
196 # default to image-file
203 # takes only one argument (id/name)
204 _jailhouse_get_id "${cur}" "${prev}" || return 1
207 # takes only one argument (id/name)
208 _jailhouse_get_id "${cur}" "${prev}" || return 1
211 # takes only one argument (id/name)
212 _jailhouse_get_id "${cur}" "${prev}" || return 1
215 _jailhouse_cell_linux || return 1
220 # this command takes only a argument at place 3
221 [ "${COMP_CWORD}" -gt 3 ] && return 1
223 COMPREPLY=( $( compgen -W "-h --help" -- "${cur}") )
226 # takes only one argument (id/name)
227 _jailhouse_get_id "${cur}" "${prev}" || return 1
229 if [ "${COMP_CWORD}" -eq 3 ]; then
230 COMPREPLY=( ${COMPREPLY[@]-} $( compgen -W "-h --help" \
241 function _jailhouse_config_create() {
244 cur="${COMP_WORDS[COMP_CWORD]}"
245 prev="${COMP_WORDS[COMP_CWORD-1]}"
247 options="-h --help -g --generate-collector -r --root -t --template-dir \
248 --mem-inmates --mem-hv"
250 # if we already have begun to write an option
251 if [[ "$cur" == -* ]]; then
252 COMPREPLY=( $( compgen -W "${options}" -- "${cur}") )
254 # if the previous was on of the following options
256 -r|--root|-t|--template-dir)
257 # search a existing directory
261 --mem-inmates|--mem-hv)
262 # we can't really predict this
267 # neither option, nor followup of one. Lets assume we want the
275 function _jailhouse() {
276 # returns two value: - numeric from "return" (success/failure)
277 # - ${COMPREPLY}; an bash-array from which bash will
278 # read the possible completions (reset this here)
281 local command command_cell command_config cur prev subcommand
284 command="enable disable cell config --help"
287 command_cell="create load start shutdown destroy linux list stats"
288 command_config="create collect"
290 # ${COMP_WORDS} array containing the words on the current command line
291 # ${COMP_CWORD} index into COMP_WORDS, pointing at the current position
292 cur="${COMP_WORDS[COMP_CWORD]}"
293 prev="${COMP_WORDS[COMP_CWORD-1]}"
295 # command line parsing for the jaihouse-tool is pretty static right
296 # now, the first two levels can be parsed simpy by comparing
299 # ${COMP_CWORD} contains at which argument-position we currently are
301 # if at level 1, we select from first level list
302 if [ "${COMP_CWORD}" -eq 1 ]; then
303 COMPREPLY=( $( compgen -W "${command}" -- "${cur}") )
305 # if at level 2, we have to evaluate level 1 and look for the main
307 elif [ "${COMP_CWORD}" -eq 2 ]; then
308 command="${COMP_WORDS[1]}"
312 # a root-cell configuration
316 # one of the following subcommands
317 COMPREPLY=( $( compgen -W "${command_cell}" -- \
321 # one of the following subcommands
322 COMPREPLY=( $( compgen -W "${command_config}" -- \
326 # these first level commands have no further subcommand
327 # or option OR we don't even know it
333 # after level 2 it gets more complecated in some cases
335 command="${COMP_WORDS[1]}"
336 subcommand="${COMP_WORDS[2]}"
340 # handle cell-commands
341 _jailhouse_cell "${subcommand}" || return 1
344 case "${subcommand}" in
346 _jailhouse_config_create || return 1
349 # config-collect writes to a new file
351 # this command takes only a argument at place 3
352 [ "${COMP_CWORD}" -gt 3 ] && return 1
361 # no further subsubcommand/option known for this
368 complete -F _jailhouse jailhouse