#!/bin/bash set -e # Author: Daniel Kahn Gillmor # Date: 2011-01-26 # License: GPL v3+ ## expect to pull these values from the environment: # VMNAME=snapper # OWNER=jrollins # RAM=512 # SMP=2 # optional, specify number of CPUs # HDA..HDZ=/path/to/disk # optional if [ -z "$VMNAME" ] ; then exit 1 fi TAP="${TAP:-${VMNAME}0}" # MAC address is derived from a hash of the host's name and the guest's name: MAC="${MAC:-$(printf "02:%s" "$(printf "%s\0%s" "$(hostname)" "${VMNAME}" | sha256sum | sed 's/\(..\)/\1:/g' | cut -f1-5 -d:)" )}" BRIDGE="${BRIDGE:-br0}" ################### OWNERGROUP=$(groups "$OWNER" | cut -f1 -d\ ) OWNERHOME=$(getent passwd "$OWNER" | cut -f6 -d: ) up() { # bring up the network tap: modprobe -v tun ip tuntap add dev "$TAP" mode tap user "$OWNER" ip link set "$TAP" up brctl addif "$BRIDGE" "$TAP" chpst -u "$OWNER:$OWNERGROUP" mkdir -p "$OWNERHOME/vms/$VMNAME" CDISO="$OWNERHOME/vms/$VMNAME/cd.iso" NETBOOT="$OWNERHOME/vms/$VMNAME/netboot" KERNEL="$OWNERHOME/vms/$VMNAME/kernel" INITRD="$OWNERHOME/vms/$VMNAME/initrd" KVMARGS= unset KERNEL_CMDLINE BOOTCHOICE=c if [ -e "$KERNEL" -a -e "$INITRD" ] ; then KVMARGS="-kernel $KERNEL -initrd $INITRD" if [ "$CMDLINE" ]; then KERNEL_CMDLINE="$CMDLINE" fi elif [ -e "$NETBOOT" ] ; then BOOTCHOICE=n elif [ -e "$CDISO" ] && [ -e $(readlink -f "$CDISO") ] ; then KVMARGS="-cdrom $CDISO" BOOTCHOICE=d fi for disk in HD{A..Z}; do if printf "%s" "${!disk}" | grep '^/dev/mapper/'; then mappername=$(printf "%s" "${!disk}" | sed 's!^/dev/mapper/!!') udevadm trigger --subsystem-match=block --attr-match=dm/name="$mappername" fi done udevadm trigger --sysname-match=kvm # older versions need to have at least the first disk marked as boot=on or they cannot boot. if kvm --version 2>/dev/null | sed 's/.*version \([0-9.]*\).*/\1/' | grep -q '^0' ; then first_disk_extra_args=",boot=on" else first_disk_extra_args= fi index=0 # set up the disks, if needed: [ -z "$HDA" ] || KVMARGS="$KVMARGS -drive file=$HDA,if=virtio,cache=none,index=$index,format=raw$first_disk_extra_args" # loop here on everything after HDA: for disk in HD{B..Z}; do index=$(( $index + 1 )) [ \! -b "${!disk}" ] || KVMARGS="$KVMARGS -drive file=${!disk},if=virtio,cache=none,index=$index,format=raw" done if [ -e /usr/share/qemu/sgabios.bin ]; then KVMARGS="$KVMARGS -device sga" fi LOGNAME="$OWNERHOME/vms/$VMNAME/console" ln -sfT "$LOGNAME" ./servicelog if [ -e "$LOGNAME" ] ; then chpst -u "$OWNER" mv "$LOGNAME" "$LOGNAME".$(date +%F_%T%z|tr : .) fi MONITORNAME="$OWNERHOME/vms/$VMNAME/monitor.socket" CONSOLENAME="$OWNERHOME/vms/$VMNAME/console.socket" kvmsend() { socat STDIO "UNIX:$MONITORNAME" <&2 exit 1 ;; esac