# vms

A command for running and managing **qemu** virtual machines

## Description

**vms** is a command that creates, edits and manages **qemu** virtual
machines. It lists, starts, stops and configures them. It also
provides shortcuts to vnc, serial and  **qemu** monitor consoles.
It is small and being written in **bash** makes it easily customizable.

Each user has a configuration file **~/.vms/vms.conf**. All the user's
virtual machines are configured in there, using a very simple format.
By editing this file the user controls the options that are passed
to **qemu**.

It has minimal dependencies, **bash** and **qemu** are needed for most of the
functionality. **vms stop** uses **socat**, **vms monitor** uses **unixterm**,
**vms serial** uses **minicom** and **vms vnc** needs **vncviewer**.

An init script **rc.vms** is also provided with a simple mechanism for
managing all the system's virtual machines. It can also be used during
the host's boot sequence to start the machines defined by the
administrator in **rc.vms.conf**.

As a bonus two scripts are provided, **pci-stub-bind** and
**vfio-bind** to ease the pain when using pci passthrough.

## Prebuild packages

slackware [vms-0.2.1-noarch-1did.tgz](https://bitbucket.org/yotis/vms/downloads/vms-0.2.1-noarch-1did.tgz)

## Latest source release

[vms-0.2.1.tar.gz](https://bitbucket.org/yotis/vms/downloads/vms-0.2.1.tar.gz)

## Latest manuals (master)

[vms(1)](https://bitbucket.org/yotis/vms/src/master/doc/man/man1/vms.1.md),
[vms.conf(5)](https://bitbucket.org/yotis/vms/src/master/doc/man/man5/vms.conf.5.md),
[rc.vms(8)](https://bitbucket.org/yotis/vms/src/master/doc/man/man8/rc.vms.8.md),
[rc.vms.conf(5)](https://bitbucket.org/yotis/vms/src/master/doc/man/man5/rc.vms.conf.5.md),
[vms-tutorial(7)](https://bitbucket.org/yotis/vms/src/master/doc/man/man7/vms-tutorial.7.md)

## Basic usage example

Show vms usage summary

    vms

Create a virtual machine named _vm1_

    vms create vm1
    qemu-img create -f qcow2 ~/.vms/vm1/disk.img 20G`

Configure _vm1_

    vms conf vm1 mem 1024
    vms conf vm1 smp 2
    vms conf vm1 disk0 '~/.vms/vm1/disk.img'
    vms conf vm1 bootcd '"$APATH/to/install-dvd-iso"'

or, edit **~/.vms/vms.conf** to configure _vm1_ like this

    # See /usr/share/vms/vms.conf.example
    vm1[arch]=x86_64
    vm1[mem]=1024
    vm1[smp]=2
    vm1[disk0]=~/.vms/vm1/disk.img
    vm1[bootcd]="$APATH/to/install-dvd.iso"

List the user's virtual machines, start vm1 and display it's status

    vms list
    vms start vm1
    vms status vm1

Stop vm1 (via ACPI command), optionally with a timeout of 10 seconds

    vms stop vm1
    vms stop vm1 10

Kill vm1 virtual machine

    vms kill vm1

If _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

## Concepts

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 files such as disk image files and bios files related to _vm1_,
although this is optional. The only required file is the script
_~/vms/vm1/vm1.sh_.

The actual **qemu** call is done in ~/.vms/vm1/vm1.sh. This file is copied
from **/var/lib/vms/vm.sh** when creating _vm1_ with \`vms create vm1\`.
This could be edited if needed or totally replaced by a custom script.
The suggested way is to configure _vm1_ by editing the appropriate section
in **vms.conf**, either by hand using your favorite editor or with
**vms conf** commands.

The section of _vm1_ in **~/.vms/vms.conf** looks like this.

    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[...

**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.

This a **bash** associative array that holds all the configuration for _vm1_. See
**/usr/share/vms/vms.conf.example** for all the available options.

## Administration

An init script **rc.vms** is provided is 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


## Directories & files

- user configuration

    `~/.vms/vms.conf`

- user configuration example

    `/usr/share/vms/vms.conf.example`

- template scripts for vm creation

    `/var/lib/vms/`

    `/var/lib/vms/vm.sh`

- vms command and parser scripts

    `/usr/bin/vms`

    `/usr/bin/vms-parse`

- helpers for pci passthrough

    `/usr/sbin/vfio-bind`

    `/usr/sbin/pci-stub-bind`

- init script

    `/etc/rc.d/rc.vms`

- init script configuration

    `/etc/rc.d/rc.vms.conf`
