From 70a8b3f4b57deed5913dd2667f892f0facd34b3d Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Sun, 22 Mar 2015 21:55:47 -0500 Subject: [PATCH] mkvm: Add script to create stand-alone Gentoo VMs --- mkvm.sh | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100755 mkvm.sh diff --git a/mkvm.sh b/mkvm.sh new file mode 100755 index 0000000..738032b --- /dev/null +++ b/mkvm.sh @@ -0,0 +1,267 @@ +#!/bin/sh + + +usage() { + echo "usage: ${0##*/} [options] name [stage_tarball [custom_script]]" +} + + +usage_full() { + usage + printf ' +Create a libvirt virtual machine running Gentoo Linux + +positional arguments: + name The libvirt domain name for the VM + stage_tarball Path to the Gentoo stage tarball to extract to the + virtual machine filesystem + custom_script Path to a script to run in the virtual machine chroot + before powering it on + +optional arguments: + -h, --help show this help message and exit + --hostname, -H The hostname of the VM (defaults to the libvirt + domain name, in all lower case) + --kernel-pkg, -K Path to a tarball containing a kernel and modules + --pool, -p The libvirt storage pool in which to create the + virtual disk + --disk-size The size of virtual disk to create (default 6 GB) + --disk-format The image format of the virtual disk (default qcow2) + --vram, -r The amount of RAM to allocate to the VM + --vcpus, -c The number of virtual CPUs to allocate to the VM + --vnet, -n The network adapter on the host to connect to the VM + --timezone, -Z The timezone to set in the VM +' +} + +invalid_arg() { + usage >&2 + echo "${0##*/}: Unrecognized argument: $1" >&2 + exit 2; +} + + +while [ $# -gt 0 ]; do + case $1 in + --hostname|-H) + shift + VHOSTNAME=$1 + shift + ;; + --kernel-pkg|-K) + shift + KERNEL_PKG=$1 + shift + ;; + --pool|-p) + shift + POOL=$1 + shift + ;; + --disk-size|-s) + shift + VDISKSIZE=$1 + shift + ;; + --disk-format|-f) + shift + VDISKFORMAT=$1 + shift + ;; + --vram|-r) + shift + VRAM=$1 + shift + ;; + --vcpus|-c) + shift + VCPUS=$1 + shift + ;; + --vnet|-n) + shift + VNET=$1 + shift + ;; + --timezone|-Z) + shift + TIMEZONE=$1 + shift + ;; + --help|-h) + usage_full + exit 0 + ;; + -*) + invalid_arg $1 + ;; + *) + if [ -z "${DOMNAME}" ]; then + DOMNAME=$1 + shift + elif [ -z "${STAGE_TBZ}" ]; then + STAGE_TBZ=$1 + shift + elif [ -z "${CUSTOMIZE}" ]; then + CUSTOMIZE=$1 + shift + else + invalid_arg $1 + fi + ;; + esac +done + + +set -e + + +if [ -z "${DOMNAME}" ]; then + usage >&2 + exit 2 +fi + +: ${VHOSTNAME:=$(printf "${DOMNAME}" | tr '[A-Z]' '[a-z]')} +: ${POOL:=default} +: ${TIMEZONE:=America/Chicago} + +unset $(env | awk -F= '/^LC_/{print $1}') +export LC_ALL=C + +mountpoint=${TMPDIR:-/tmp}/${VHOSTNAME} +mkdir ${mountpoint} + + +virsh vol-create-as ${POOL} ${DOMNAME}.img \ + --capacity ${VDISKSIZE:-6G} \ + --format ${VDISKFORMAT:-qcow2} +vol_path=$(virsh vol-path ${DOMNAME}.img ${POOL}) + +echo 'Creating logical volumes and filesystems ...' +i=$(pgrep -fa ^nbd | sort -k2r | sed -rn '1s/[0-9]+\s+nbd//p') +blkdev=/dev/nbd$((${i:--1} + 1)) +unset i + +sudo /bin/sh -e < /dev/null + +pvcreate ${blkdev}p3 +vgcreate ${VHOSTNAME} ${blkdev}p3 +lvcreate -nswap -L1G ${VHOSTNAME} +lvcreate -nroot -L300M ${VHOSTNAME} +lvcreate -nusr -L1200M ${VHOSTNAME} +lvcreate -nvar -L600M ${VHOSTNAME} +lvcreate -nopt -L100M ${VHOSTNAME} +lvcreate -nhome -L100M ${VHOSTNAME} +mkswap -Lswap /dev/${VHOSTNAME}/swap +mkfs.ext4 -q -Lboot ${blkdev}p2 +for v in root usr var opt home; do + mkfs.xfs -q -L\$v /dev/${VHOSTNAME}/\$v +done +EOS + +[ -z "${STAGE_TBZ}" ] && exit 0 + +echo 'Mounting filesystems ...' +sudo /bin/sh -e < ${mountpoint}/boot/grub/grub.cfg < ${mountpoint}/etc/fstab < ${mountpoint}/etc/timezone + +passwd -R ${mountpoint} -d root +EOS + + +if [ -n "${KERNEL_PKG}" ]; then + echo 'Extracting kernel package ...' + sudo tar --no-same-owner --no-same-permissions --strip-components=1 \ + --dereference -xaf "${KERNEL_PKG}" -C ${mountpoint} +fi + + +if [ -f "${CUSTOMIZE}" ]; then + echo 'Customizing ...' + sudo /bin/sh "${CUSTOMIZE}" +fi + + +echo 'Cleaning up ...' +awk '$5~/'${VHOSTNAME}'/{print $5}' /proc/self/mountinfo | tac \ + | xargs sudo umount +sudo vgchange -an ${VHOSTNAME} +sudo qemu-nbd -d ${blkdev} + +virt-install --name ${DOMNAME} \ + --ram ${VRAM:-1024} \ + --vcpus ${VCPUS:-2} \ + --os-type linux \ + --os-variant rhel7 \ + --boot hd \ + --disk ${vol_path} \ + --network bridge=${VNET:-br0} \ + --graphics vnc \ + --video cirrus \ + --memballoon model=virtio \ + --noautoconsole + +rmdir ${mountpoint}