Google Summer of Code 2016/Making virsh more bash like

From Libvirt Wiki
Jump to: navigation, search

Over the summer of 2016, I was working on Making virsh more bash like. Virsh is an executable, part of the software provided by libvirt, to manage virtual machines. It works in both interactive mode(as a shell), and in non-interactive mode as well, as a commandline utility.

People who have used virsh might say that it is not so user friendly when it comes to tab-completion, and I/O redirection. In the interactive mode, there is minimal tab-completion, while there is no I/O redirection, and in the non-interactive mode, there is no tab-completion and the I/O redirection is handled by the background shell(Bash for example). The main aim of this project is to bring virsh closer to bash, by improving the tab-completion behavior and adding support for I/O redirection.

Tab Completion


Tab completion broadly has three stages in virsh (in the interactive mode, non-interactive mode has no tab completion yet):

  • Command completion, where on pressing TAB, a command is auto-completed or multiple commands are suggested. For example:
virsh # l[TAB][TAB]
list                 lxc-enter-namespace
virsh # li[TAB][TAB] <-- completes it to "list"
  • Option completion, where on pressing TAB, a corresponding option is auto-completed or multiple options are suggested. For example:
virsh # list --a[TAB][TAB]
--all        --autostart  
virsh # list --al[TAB] <-- completes to "--all"
  • Argument/Data completion, where on pressing TAB, arguments corresponding to an option are completed.
virsh # vol-dumpxml --pool [TAB][TAB]
pool1        pool2

First set of patches

Virsh, before this project provided the first two functionalities, i.e., command completion and option completion, but these were very limited in the following ways:

  • Tab completion failed if tab completion was attempted on unsanitary input, i.e., on input that contained quotes or in some cases, extra or leading whitespace.
  • Tab completion failed on multiple commands, delimited by a semicolon.
virsh # list;[TAB][TAB] <-- This would fail and give out options corresponding to "list" command instead of command completion.

In these patches, I introduced a new function vshReadlineParse, that addressed the above limitations(minimal quotes handling though). The added advantage of this was that, it was pretty easy to extend this function to allow calling option completers as discussed below.

Option Completers

The next step was to extend the vshReadlineParse function to incorporate usage of option completers. Option completers in virsh are functions that provide possible auto-completions for a particular combination of a command and option. Since there are many possible valid combinations of a command and its corresponding options, defining a completer for each of the options is not feasible. So, the idea is to have bitwise flags for every option that indicate what kind of behavior they would want from their corresponding completer, and then write common completers for options that have similar behavior, and the exact behavior desired is achieved by passing in these bitwise flags.

For example, assume that we have three VMs defined, dom1, dom2 and fedora. dom1 is running, while dom2> is paused, and fedora is shut off.

virsh # start --domain [TAB][TAB] <-- we would want this to call the option completer for the "domain" option to list the shutoff VMs
virsh # shutdown --domain [TAB][TAB] <-- call the option completer for the "domain" option to list the running or paused VMs
dom1        dom2

From the above example, we can say that we can use a common completer for the domain option of start as well as shutdown command, and differentiate in their behavior using simple flags which indicate if we want all the domains, or if we want the domains that are running etc.

These patches extend vshReadlineParse to allow for option completers to be called if they are defined, along with some minor improvements over the previous patches.

Defining the completers

Once we have the option completer code in vshReadlineParse set, the next step would be to define the corresponding vshCompleters. Now, some vshCompleters might require access(a connection) to libvirtd, and some might not. That means, the completers must have access to a vshControl that is connected to libvirtd, or can be connected to libvirtd. So, the first thing to here would be to change the signature of vshCompleter to pass additional data needed by a completer as and when needed in the form of a void pointer. The related patch can be found here(yet to be proposed on the list).

After this, I have attempted to address the issue of some completers requiring a connection to libvirtd. If a command's option completer requires a connection to libvirtd, completion from that particular completer is attempted only if there is an existing connection to the libvirt daemon. The reason behind this is that, in principle auto-completion should not have the power to initiate connections between a client(virsh in this case), and the libvirtd, as it may cause authentication issues in some cases. So, in these three patches, a new function was introduced that checks if a vshControl's connection to libvirtd is active or not, and if it is active, only then a completer that needs a connection to libvirtd is called.

Next, I have written vshDomainCompleter(again, yet to be proposed on the list), as an example vshCompleter, that might be used for completing domain names when required by different options. Flags can be passed to filter the domain names based on their state like paused, shutoff, running etc.

Pending work

Tab completion in interactive mode

From here on, the following steps remain with regards to tab-completion in the interactive mode:

  • Propose these patches on the list and iterate after receiving feedback over them.
  • Define remaining vshCompleters for all the options, which will be an ongoing process.
  • Fix bugs as they are identified over time.

Tab completion in non-interactive mode

All the work mentioned above has been about tab completion in interactive mode. To improve tab-completion in the non-interactive mode, I plan to introduce a new command, complete for virsh, that would make use of the tab completion functionality implemented already and make appropriate calls to the vshReadline* family of functions to get the possible completions, if any. Then, implementing tab-completion in non-interactive mode would boil down to having a bash-completion script, the meat of which would be:

virsh complete "$@"

I/O Redirection

The main aim of this GSoC project was to primarily work on improving tab completion, and if time permits, move to working on I/O redirection. Since tab completion itself wasn't fully completed, work is yet to begin on I/O redirection part. Once tab-completion has been sufficiently completed, I'll begin work on I/O redirection.

Patches Summary

Below are links to individual patches proposed by me, along with a one line description generated by git log --oneline --reverse --author="Nishith Shah".

  • 1617134 virsh: blkdeviotune: accept human readable values for bytes
  • 30677a7 qemu: parse: Use qemuParseCommandLineMem for -m memory
  • 701b0f1 qemu: parse: Handle suffixes for -m memory
  • 2432521 virsh: Break vshCmddefOptParse into helper functions
  • d7079ec virsh: Fix variable types in readline generators
  • aceb630 virsh: Add option to suppress error in various functions
  • 3987eba virsh: Introduce vshReadlineParse for improved auto-completion
  • dcfdf34 virsh: Introduce usage of option completers to auto-complete arguments
  • 2550579 virsh: Allow data or argument options to be completed as well
  • 731ee28 virsh: Complete multiple options when any one option requires data
  • f4a8d5a tools: Pass opaque data in vshCompleter and introduce autoCompleteOpaque
  • 428990a tools: Add option to suppress output from vshConnectionHook
  • 1e2b89d tools: Introduce connUsability in vshClientHook
  • 167b4b5 tools: Use connUsability to check for a connection before auto-completion
  • df551d7 tools: Introduce vshDomainCompleter in virsh-completer.c

Note: The links to github commits might change(because of rebasing/amending). While I will try to keep this section updated with working links, if a link is defunct or outdated, please drop me an email regarding it and I will fix the links. Also, please feel free to get in touch with me in case you find any kind of errors, including typos in the whole page.