268 lines
5.7 KiB
Bash
Executable File
268 lines
5.7 KiB
Bash
Executable File
#!/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}
|