mkvm: Add script to create stand-alone Gentoo VMs
parent
380aa823d9
commit
70a8b3f4b5
|
@ -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 <<EOS
|
||||
qemu-nbd -c ${blkdev} ${vol_path}
|
||||
|
||||
sgdisk -a 4096 -Z -g \
|
||||
-n 1::+1M \
|
||||
-t 1:EF02 \
|
||||
-c 1:'BIOS boot partition' \
|
||||
-n 2::+32M \
|
||||
-c 2:'Linux filesystem' \
|
||||
-n 3:: \
|
||||
-t 3:8E00 \
|
||||
-c 3:'Linux LVM' \
|
||||
${blkdev}
|
||||
|
||||
pvscan > /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 <<EOS
|
||||
mount /dev/${VHOSTNAME}/root ${mountpoint}
|
||||
|
||||
install -d ${mountpoint}/boot
|
||||
mount ${blkdev}p2 ${mountpoint}/boot
|
||||
|
||||
for v in usr var opt home; do
|
||||
install -d ${mountpoint}/\$v
|
||||
mount /dev/${VHOSTNAME}/\$v ${mountpoint}/\$v
|
||||
done
|
||||
EOS
|
||||
|
||||
echo 'Extracting stage tarball ...'
|
||||
sudo tar -xaf "${STAGE_TBZ}" -C ${mountpoint}
|
||||
|
||||
echo 'Configuring system ...'
|
||||
sudo /bin/sh -e <<EOS
|
||||
mount -t proc proc ${mountpoint}/proc
|
||||
mount -t sysfs sysfs ${mountpoint}/sys
|
||||
mount -obind /dev ${mountpoint}/dev
|
||||
chroot ${mountpoint} grub2-install ${blkdev}
|
||||
cat > ${mountpoint}/boot/grub/grub.cfg <<EOF
|
||||
timeout=1
|
||||
|
||||
menuentry 'Gentoo Linux' {
|
||||
root=hd0,gpt2
|
||||
linux /vmlinuz root=/dev/${VHOSTNAME}/root dolvm net.ifnames=0 quiet
|
||||
initrd /initramfs
|
||||
}
|
||||
EOF
|
||||
|
||||
sed -i s/localhost/${VHOSTNAME}/ ${mountpoint}/etc/conf.d/hostname
|
||||
|
||||
cat > ${mountpoint}/etc/fstab <<EOF
|
||||
LABEL=swap none swap sw 0 0
|
||||
LABEL=boot /boot ext4 noauto,noatime 1 2
|
||||
/dev/${VHOSTNAME}/root / xfs ro,noatime 0 1
|
||||
/dev/${VHOSTNAME}/usr /usr xfs ro,noatime 0 2
|
||||
/dev/${VHOSTNAME}/var /var xfs noatime 0 2
|
||||
/dev/${VHOSTNAME}/opt /opt xfs ro,noatime 0 2
|
||||
/dev/${VHOSTNAME}/home /home xfs noatime 0 2
|
||||
tmpfs /tmp tmpfs defaults 0 0
|
||||
EOF
|
||||
|
||||
rm -rf ${mountpoint}/run/openrc
|
||||
ln -snf /proc/self/mounts ${mountpoint}/etc/mtab
|
||||
ln -snf /run/resolv.conf ${mountpoint}/etc/resolv.conf
|
||||
ln -snf /run/ntp.conf ${mountpoint}/etc/ntp.conf
|
||||
|
||||
ln -snf /usr/share/zoneinfo/${TIMEZONE} ${mountpoint}/etc/localtime
|
||||
echo ${TIMEZONE} > ${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}
|
Loading…
Reference in New Issue