147 lines
3.9 KiB
Bash
Executable File
147 lines
3.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# Creates a new virtual machine from the given stage4 tarball
|
|
|
|
DOMNAME="$1"
|
|
STAGE_TBZ="$2"
|
|
VMNAME=$(echo "${DOMNAME}" | tr '[:upper:]' '[:lower:]')
|
|
VM_FQDN="${VMNAME}.$(hostname -d)"
|
|
|
|
if [[ -z $STAGE_TBZ || -z $VMNAME ]]; then
|
|
echo "Usage: $(basename $0) <vmname> <stage4-tarball>" >&2
|
|
exit 2
|
|
fi
|
|
|
|
: ${VG:=vmachines}
|
|
: ${POOL:=LVM}
|
|
: ${DOMXML_TMPL:=/etc/libvirt/qemu/_template.xml}
|
|
: ${MOUNTPOINT:=/mnt/new_vmachine}
|
|
: ${PORTAGE_PROFILE:="default/linux/amd64/13.0"}
|
|
: ${VM_TZ:=America/Chicago}
|
|
|
|
|
|
quit() {
|
|
exit "$@"
|
|
}
|
|
|
|
cleanup() {
|
|
local mnt
|
|
echo "Failed! Cleaning up..."
|
|
sync ; sync ; sync
|
|
if [ -n "${MOUNTPOINT}" ]; then
|
|
for d in home usr var run tmp ""; do
|
|
mnt="${MOUNTPOINT}"/$d
|
|
mountpoint -q "${mnt}" && umount -l "${mnt}"
|
|
done
|
|
fi
|
|
vgchange -an ${VMNAME}
|
|
lvchange -an ${VG}/${VMNAME}
|
|
virsh -c qemu:///system vol-delete ${VMNAME} ${POOL}
|
|
}
|
|
|
|
|
|
while [[ -z ${VM_ROOTPW} ]]; do
|
|
read -sp 'New VM root password: ' VM_ROOTPW
|
|
echo
|
|
read -sp 'Confirm root password: ' confirm_rootpw
|
|
echo
|
|
if [[ ${VM_ROOTPW} != ${confirm_rootpw} ]]; then
|
|
echo "Passwords don't match" >&2
|
|
unset VM_ROOTPW
|
|
fi
|
|
done
|
|
|
|
set -e
|
|
|
|
PORTDIR=$(portageq envvar PORTDIR)
|
|
DISTDIR=$(portageq envvar DISTDIR)
|
|
PKGDIR=$(portageq envvar PKGDIR)
|
|
|
|
if lvdisplay ${VG}/${VMNAME} >/dev/null 2>&1; then
|
|
echo "ERROR: Logical volume ${VMNAME} already exists in group ${VG}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Creating storage volume..."
|
|
virsh -c qemu:///system vol-create-as ${POOL} ${VMNAME} 2G
|
|
|
|
echo "Creating LVM volumes..."
|
|
pvcreate /dev/${VG}/${VMNAME}
|
|
vgcreate ${VMNAME} /dev/${VG}/${VMNAME}
|
|
lvcreate -nroot -L100M ${VMNAME}
|
|
lvcreate -nhome -L200M ${VMNAME}
|
|
lvcreate -nvar -L400M ${VMNAME}
|
|
lvcreate -nusr -l100%FREE ${VMNAME}
|
|
|
|
trap "quit" INT TERM
|
|
trap "cleanup" EXIT
|
|
|
|
echo "Creating XFS filesystems..."
|
|
for fs in root home usr var; do
|
|
mkfs.xfs -L$fs -q /dev/${VMNAME}/$fs
|
|
done
|
|
|
|
echo "Mounting filesystems..."
|
|
[[ ! -d "${MOUNTPOINT}" ]] && mkdir -p "${MOUNTPOINT}"
|
|
mount /dev/${VMNAME}/root "${MOUNTPOINT}"
|
|
for fs in home usr var; do
|
|
mkdir "${MOUNTPOINT}"/$fs
|
|
mount /dev/${VMNAME}/$fs "${MOUNTPOINT}"/$fs
|
|
done
|
|
mkdir "${MOUNTPOINT}"/run
|
|
mount -t tmpfs tmpfs "${MOUNTPOINT}"/run
|
|
|
|
echo "Extracting stage tarball..."
|
|
tar -xjpf "${STAGE_TBZ}" -C "${MOUNTPOINT}"
|
|
|
|
echo "Setting hostname..."
|
|
sed -i "s/localhost/${VMNAME}/" "${MOUNTPOINT}"/etc/conf.d/hostname
|
|
|
|
echo "Setting time zone..."
|
|
rm -f "${MOUNTPOINT}"/etc/localtime
|
|
ln -s /usr/share/zoneinfo/${VM_TZ} "${MOUNTPOINT}"/etc/localtime
|
|
echo ${VM_TZ} > "${MOUNTPOINT}"/etc/timezone
|
|
|
|
echo "Configuring network..."
|
|
echo 'config_eth0="dhcp"' > "${MOUNTPOINT}"/etc/conf.d/net
|
|
ln -s net.lo "${MOUNTPOINT}"/etc/init.d/net.eth0
|
|
ln -s /etc/init.d/net.eth0 "${MOUNTPOINT}"/etc/runlevels/default/
|
|
|
|
for keytype in dsa rsa ecdsa; do
|
|
key="${MOUNTPOINT}"/etc/ssh/ssh_host_${keytype}_key
|
|
echo "Creating ${keytype} SSH host key..."
|
|
ssh-keygen -t ${keytype} -f "${key}" -N '' || true
|
|
done
|
|
|
|
echo "Configuring fstab..."
|
|
cat << EOF > "${MOUNTPOINT}"/etc/fstab
|
|
/dev/${VMNAME}/root / xfs ro,noatime 0 1
|
|
/dev/${VMNAME}/usr /usr xfs ro,noatime 0 2
|
|
/dev/${VMNAME}/var /var xfs noatime 0 2
|
|
/dev/${VMNAME}/home /home xfs noatime 0 2
|
|
tmpfs /tmp tmpfs defaults 0 0
|
|
EOF
|
|
|
|
echo "Creating read-only root filesystem compatibility symlinks..."
|
|
rm -f "${MOUNTPOINT}"/etc/{resolv,ntp}.conf
|
|
rm -f "${MOUNTPOINT}"/etc/mtab
|
|
ln -s /proc/self/mounts "${MOUNTPOINT}"/etc/mtab
|
|
ln -s /run/resolv.conf "${MOUNTPOINT}"/etc/resolv.conf
|
|
ln -s /run/ntp.conf "${MOUNTPOINT}"/etc/ntp.conf
|
|
|
|
echo "Setting root password..."
|
|
echo "root:${VM_ROOTPW}" | chroot "${MOUNTPOINT}" chpasswd
|
|
|
|
echo "Enabling serial console..."
|
|
sed -i 's/#s0/s0/' "${MOUNTPOINT}"/etc/inittab
|
|
|
|
trap - INT TERM EXIT
|
|
|
|
echo "Cleaning up..."
|
|
umount "${MOUNTPOINT}"/{run,usr,var,home,}
|
|
vgchange -an ${VMNAME}
|
|
|
|
echo "Creating libvirt domain..."
|
|
virsh -c qemu:///system define <(m4 -P -DNAME="${DOMNAME}" "${DOMXML_TMPL}")
|
|
echo "Starting virtual machine..."
|
|
virsh -c qemu:///system start ${DOMNAME}
|