# 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

## Latest source release

vms-0.2.1.tar.gz

## Latest manuals (master)

vms(1), vms.conf(5), rc.vms(8), rc.vms.conf(5), vms-tutorial(7)

## 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`