#!/bin/sh # # Define and install a libvirt domain # # Copyright 2013 Guilhem Moulin # # Licensed under the GNU GPL version 3 or higher. # set -ue root=$(dirname "$0") help() { cat >&2 <<-EOF Usage: $0 install [] Install the given domain, using the given image (created if necessary) as a disk. $0 view Open a connection to a running domain using the Spice protocol EOF exit 1 } get_XML_attribute() { local domain="$1" object="$2" attribute="$3" /usr/bin/virsh dumpxml "$domain" \ | /usr/bin/xmlstarlet sel -t -m /domain/"$object" -v @"$attribute" } doesExist() { /usr/bin/virsh -r list --all --name | grep -qxF "$1" } isActive() { /usr/bin/virsh -r list --name | grep -qxF "$1" } install() { [ $# -eq 1 -o $# -eq 2 ] || help local name=$1 local disk=${2:-$root/images/${name}.qcow2} local darch version=$(sed -n 's/^VERSION\s*=\s*//p' $root/../preseed/Makefile) case "${ARCH:=$(/bin/uname -m)}" in i386|i686) darch=i386;; x86_64) darch=amd64;; *) darch=$ARCH;; esac local cdrom="$root/../preseed/dist/$darch/debian-$version-$darch-netinst-preseeded.iso" if doesExist "$name"; then echo "Error: Domain $name already exists. If you want to replace the domain, run" >&2 echo >&2 isActive "$name" && echo " virsh destroy $name" >&2 echo " virsh undefine $name" >&2 exit 1 fi if ! [ -f "$cdrom" -a -r "$cdrom" ]; then cat >&2 <<- EOF Error: '$cdrom' does not exist or is not readable. To create the preseeded image, run cd $root/../preseed ARCH=$darch make iso-preseed EOF exit 1 fi grep -q '^kvm\s' /proc/modules || echo 'WARN: KVM not available!' >&2 if ! [ -r "$disk" -a -r "$disk" ]; then local size=12G echo "Creating (sparse) $size disk image '$disk'" >&2 /usr/bin/qemu-img create -f "${disk##*.}" \ -o size="$size",preallocation=metadata "$disk" fi # TODO: the bus should be chosen at random among sata,ide,scsi,usb # TODO: test EFI: http://www.linux-kvm.org/page/OVMF /usr/bin/virt-install -q \ --name "$name" \ --arch "$ARCH" \ --ram 128 \ --cdrom "$cdrom" \ --disk "$disk",cache=writeback,bus=sata \ --network network=default \ --graphics spice cat >&2 <<- EOF Domain '$name' has been created. As you can see in virsh list it should now be up and running. To open a graphical console, run $0 view $name EOF } view(){ [ $# -eq 1 ] || help local domain="$1" if ! doesExist "$domain"; then cat >&2 <<- EOF Error: Domain $domain does not exist. To create it, run ./virt install $domain EOF exit 1 elif ! isActive "$domain"; then echo "Error: Domain $domain is not active" >&2 exit 1 fi local type=$(get_XML_attribute "$domain" devices/graphics type) local port=$(get_XML_attribute "$domain" devices/graphics port) || true if [ "$type" != spice -o -z "$port" ]; then echo "Error: Could not find a valid Spice server on domain '$domain'." >&2 exit 1 fi /usr/bin/spicec -h 127.0.0.1 -p $port } command="${1:-}" shift; case "$command" in install|view) $command "$@";; *) help esac