#!/bin/bash # depends on following packages: # apt-get install virtinst libvirt-bin dosfstools mtools kvm xmlstarlet # For resizing the root partition we tried two ways: # sfdisk # ------ # For sfdisk we need util-linux >= 2.17.2-3 (debian wheezy, ubuntu oneiric), # because of the sfdisk-feature which lets us script the growing of the root partition. # see https://bugs.launchpad.net/ubuntu/+source/util-linux/+bug/686124 # apt-get install -t wheezy util-linux # parted # ------ # seems to be more robust than sfdisk, so we use that approach # unfortunatly, there's no way to resize a partition with parted >= 2.4 # deleting and recreating is the only way, which leaves us with an # dirty workaround, giving the beginning of the root partition in sectors # with the variable $ROOT_PARTITION_BEGINNING # defaults, configurable in config VG='vg01' ETC='/etc/libvirt/local/cloudinit' CONFIG="$ETC/cloudinit.cfg" VARDIR='/var/lib/libvirt/cloudinit' SCRIPTDIR='/usr/local/bin/leap_cloudadmin' KVM_URI='qemu:///system' SEED='cloudinit_seed.img' BASEIMAGE='leap-baseimage' SWAPUUID='3a79d708-2a74-4344-a953-15e955dbdae7' # Defaults for leap-baseimage, change if you # have a different disk layout ROOT_PARTITION_NR='2' ROOT_PARTITION_BEGINNING='4096s' # unconfigurable variables MIN_ROOTSIZE=2 DEFAULT_SWAPSIZE=512 DEFAULT_MEM=512 rootsize=$MIN_ROOTSIZE swapsize=$DEFAULT_SWAPSIZE memsize=$DEFAULT_MEM # overwrite defaults [ -e $CONFIG ] && . $CONFIG [ -z "$LC_ALL" ] && LC_ALL="en_US.UTF-8" fail() { [ $# -eq 0 ] || echo "$@"; exit 1; } bad_usage() { usage 1>&2; [ $# -eq 0 ] || fail "$@"; exit 1; } usage() { cat < -s -n guest_name Creates a new guest VM using cloud-init to utilize nocloud. Uses $ETC/.cfg as meta- und user-data file options: -h show usage -r size root size in GB. Defaults to minimal value of $MIN_ROOTSIZE GB. -s size swap size in MB. Defaults to $DEFAULT_SWAPSIZE MB. -m size memory size in kibibytes. Defaults to $DEFAULT_MEM KiB. -n name guestname EOF } # Parse cmdline options while getopts "hr:s:n:m:" OPTION do #echo $OPTION $OPTARG case $OPTION in h) usage exit 0;; r) rootsize=$OPTARG;; s) swapsize=$OPTARG;; n) vmname=$OPTARG;; m) memsize=$OPTARG;; esac done [ -z $vmname ] && bad_usage "must provide guest name" [ $# -gt 8 ] && bad_usage "too many arguments" [ $rootsize -lt $MIN_ROOTSIZE ] && bad_usage "Minimal root size is $MIN_ROOTSIZE GB !" cfg="$ETC/$vmname.cfg" rootdev="/dev/$VG/${vmname}-root" swapdev="/dev/$VG/${vmname}-swap" # requirements echo "mtools_skip_check=1">~/.mtoolsrc [ -e $VARDIR ] || ( mkdir $VARDIR ; chown libvirt-qemu $VARDIR ) [ -e $rootdev ] && fail "$rootdev exists - please delete it or choose another guest name" [ -e $swapdev ] && fail "$swapdev exists - please delete it or choose another guest name" [ -e $cfg ] || fail "please provide config file in $cfg" echo echo "Creating guest VM $vmname:" echo "Root size: $rootsize GB, using $rootdev" echo "Swap size: $swapsize MB, using $swapdev" echo "Memory size: $memsize KiB" echo "" echo "using $cfg for cloud-init" echo echo "OK ? to abort, to resume." read enter # is a VM with the same name defined ? virsh dominfo $vmname > /dev/null 2>&1 if [ $? -eq 0 ]; then fail "Domain $vmname is defined in libvirt. Please undefine first."; fi # create root and swap disk lvcreate -L ${rootsize}g -n ${vmname}-root $VG lvcreate -L ${swapsize}m -n ${vmname}-swap $VG mkswap -U $SWAPUUID $swapdev sleep 4 virt-clone --connect $KVM_URI -o $BASEIMAGE -n $vmname -f $rootdev --force # Set memory tmpxml=`mktemp` virsh dumpxml ${vmname} > $tmpxml xmlstarlet edit -L -u "/domain[@type='kvm']/memory[@unit='KiB']" -v "${memsize}" $tmpxml virsh define $tmpxml rm -f $tmpxml # resize root partition # echo ",+," | sfdisk -q -N2 /dev/$VG/$vmname > /dev/null 2>&1 # sfdisk is unreliable for us and doesn't work on a new kvm host parted $rootdev --script -- rm $ROOT_PARTITION_NR parted $rootdev --script -- mkpart primary $ROOT_PARTITION_BEGINNING -1s # create cloudinit seed disk csplit -q --prefix "$VARDIR/$vmname" $cfg '/#cloud-config/' metadata="$VARDIR/${vmname}00" userdata="$VARDIR/${vmname}01" $SCRIPTDIR/libvirt-make-seed-disk $VARDIR/$vmname-$SEED $userdata $metadata echo echo "Cloudinit-seeddisk is at $VARDIR/$vmname-$SEED, attaching after booting" echo echo "Finished creating guest $vmname. Enjoy." echo echo "Press to start the new guest." read bogus echo echo 'Starting new guest, attaching to console. Exit with Ctrl+]' echo virsh start $vmname sleep 2 # create seed- and swapdisk definition and attach them virsh attach-disk $vmname --source $swapdev --target vdb --config virsh attach-disk $vmname --source $VARDIR/$vmname-$SEED --target vdc --sourcetype file --type disk --driver qemu --subdriver raw --config virsh setmem $vmname $memsize --live --config virsh console $vmname