A collection of bash
scripts for running qemu
virtual machines
Simple bash
scripts for easy creation and management of qemu
virtual machines. The whole system is to be used as a helper to generate the qemu
command line using a single configuration file for each user of the system ~/.vms/vms.conf
.
A command line utility is provided, vms
that can be used to create and manage virtual machines. The user edits his ~/.vms/vms.conf
file to add more options, such as more devices or raw qemu
command line options. The vms
utility can also be used to list, start, stop, kill the configured virtual machines and provides access to vnc, serial and qemu
monitor consoles.
It has minimal dependencies, bash
and qemu
are needed for most of the functionality. vms stop
uses socat
, vms monitor
uses unixterm
from the vde2
package, vms serial
uses minicom
and vms vnc
needs vncviewer
.
An init script rc.vms
is also provided with a simple mechanism for the administrator to enable staring any user's virtual machine on host boot by editing rc.vms.conf
.
As a bonus two scripts are provided, pci-stub-bind
and vfio-bind
to ease the pain when using pci passthrough.
slackware vms-0.1.3-noarch-1did.tgz
vms
vms create vm1
cd ~/.vms/vm1
qemu-img create -f qcow2 disk1.img 20G
~/.vms/vms.conf
to configure vm1.Eg, add the following and adjust the paths. See /usr/share/vms/vms.conf.example
for available options.
vm1[arch]=x86_64
vm1[mem]=1024
vm1[smp]=2
vm1[disk0]="$APATH/.vms/vm1/disk1.img"
vm1[bootcd]="$APATH/to/install-dvd.iso"
#If you want vnc and 'vms start vm1' to return, use the following
#vm1[vnc]=17
#vm1[daemon]=yes
vms list
vms start vm1
vms status vm1
vms stop vm1
Can also be used with a timeout for 10 seconds like this
vms stop vm1 10
vms kill vm1
vms restart vm1
Can also be used with a timeout parameter
vms restart vm1 10
Assuming vm1 is configured with monitor, serial, vnc or log, the following can be used to access them
vms vnc vm1
vms monitor vm1
vms serial vm1
vms log vm1
The general idea is to have a directory with a bash script for each virtual machine. All these directories are stored per user inside ~/.vms directory.
For each user there is a ~/.vms/vms.conf file that contains all the configuration for all the user's virtual machines. The configuration for each virtual machine is kept as one bash associative array, declared in the user's vms.conf file. The system has a very simple parser that matches keys of this array to generate the qemu command line options for most commonly used options, such as cpu, disk#, nic#, mem, etc. Raw command line options are also supported, as well as providing the option to totally bypass the parser and use a custom bash script that calls qemu bypassing the whole system.
A typical ~/.vms directory looks like this
~/.vms
~/.vms/vms.conf
~/.vms/vm1/vm1.sh
~/.vms/vm1/disk1.img
~/.vms/vm2/vm2.sh
~/.vms/vm2/....
For each virtual machine there is a directory under ~/.vms, eg. for vm1 there is a directory named ~/.vms/vm1. This can be used to store any more files such as disk image files, bios files related to vm1, although this is optional. The only required file there is a script ~/vms/vm1/vm1.sh. Both the directory and the script are created during `vms create vm1`.
Following the vm1 example, there is a script ~/vms/vm1/vm1.sh. This is called and it actually launches qemu and is copied from /var/lib/vms/vm.sh when creating vm1 with `vms create vm1`. This should be edited as needed or totally replaced by a custom script. The suggested way is to configure vm1 is by editing the appropriate section in vms.conf.
The section of vm1 in ~/.vms/vms.conf
looks like this. name, uuid and arch are needed by vms for each virtual machine. vms identifies the qemu process by the uuid, so no virtual machine can be started twice.
declare -A vm1
vm1[name]='vm1'
vm1[uuid]='ffffffff-ffff-ffff-ffff-ffffffffffff'
vm1[arch]='x86_64'
vm1[kvm]=yes
vm1[cpu]=host
vm1[smp]=2
vm1[mem]=1024
vm1[...
This a bash associative array that holds all the configuration for vm1. See /usr/share/vms/vms.conf.example
for all the available options. The command vms create vm1
creates the directory, copies ~/vms/vm1/vm1.sh
script and appends the first four lines of the configuration above inside ~/.vms/vms.conf
.
An init script rc.vms
is provided that can be used to launch a set of virtual machines during boot. Assuming the host keeps this init script in /etc/rc.d/
, the root user can use the following line with the host's init system to start the virtual machines defined in rc.vms.conf
.
/etc/rc.d/rc.vms start
Accordingly, one can use the following to restart and stop the machines in the set.
/etc/rc.d/rc.vms restart
/etc/rc.d/rc.vms stop
The following diplays the status of the machines.
/etc/rc.d/rc.vms status
Also, rc.vms
can be used to call any vms
command as any user. Assuming the user joe has a machine named vm1, the root user can use this script like this to display information about vm1
/etc/rc.d/rc.vms cmd joe info vm1
Accordingly root can start, stop and restart vm1 like this
/etc/rc.d/rc.vms cmd joe start vm1
/etc/rc.d/rc.vms cmd joe stop vm1
/etc/rc.d/rc.vms cmd joe restart vm1
When launching the vm1 machine with the following line in ~/.vms/vms.conf
vm1[secure]=yes
then only the root user can launch vm1, since root privileges are needed to chroot and run as nobody. If this is not set, rc.vms
will start the qemu process as the normal user joe.
/etc/rc.d/rc.vms cmd joe start vm1
user configuration file
~/.vms/vms.conf
user configuration file example
/usr/share/vms/vms.conf.example
template scripts for vm creation
/var/lib/vms/
/var/lib/vms/vm.sh
main user interface script
/usr/bin/vms
parser script
/usr/bin/vms-parse
helpers for pci passthrough
/usr/sbin/vfio-bind
/usr/sbin/pci-stub-bind
init script
/etc/rc.d/rc.vms
virtual machines configured to launch on boot
/etc/rc.d/rc.vms.conf