create-vmachine: Initial commit
commit
4b357bee36
|
@ -0,0 +1,162 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Creates a new virtual machine from the given stage3 tarball
|
||||||
|
|
||||||
|
DOMNAME="$1"
|
||||||
|
STAGE_TBZ="$2"
|
||||||
|
VMNAME=$(echo "${DOMNAME}" | tr '[:upper:]' '[:lower:]')
|
||||||
|
VM_FQDN="${VMNAME}.$(hostname -d)"
|
||||||
|
|
||||||
|
VG=vmachines
|
||||||
|
POOL=LVM
|
||||||
|
DOMXML_TMPL=/etc/libvirt/qemu/_template.xml
|
||||||
|
MOUNTPOINT=/mnt/new_vmachine
|
||||||
|
PUPPETMASTER=$(hostname -f)
|
||||||
|
PORTAGE_PROFILE="default/linux/amd64/13.0"
|
||||||
|
|
||||||
|
PORTDIR=$(portageq envvar PORTDIR)
|
||||||
|
DISTDIR=$(portageq envvar DISTDIR)
|
||||||
|
PKGDIR=$(portageq envvar PKGDIR)
|
||||||
|
|
||||||
|
if [[ -z $STAGE_TBZ || -z $VMNAME ]]; then
|
||||||
|
echo "Usage: $(basename $0) <vmname> <stage3-tarball>" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if lvdisplay ${VG}/${VMNAME} >/dev/null 2>&1; then
|
||||||
|
echo "ERROR: Logical volume ${VMNAME} already exists in group ${VG}" >&2
|
||||||
|
exit 2
|
||||||
|
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}
|
||||||
|
|
||||||
|
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 "Installing critical packages..."
|
||||||
|
# Installing packages must be done in a chroot instead of using the $ROOT
|
||||||
|
# Portage environment variable because several ebuilds use enewuser/enewgroup
|
||||||
|
# to create system users, which creates the user on the host system, not the
|
||||||
|
# target system. See Gentoo bug #53269 for details on the problem.
|
||||||
|
|
||||||
|
mkdir "${MOUNTPOINT}"/usr/portage
|
||||||
|
mount -obind "${PORTDIR}" "${MOUNTPOINT}"/usr/portage
|
||||||
|
mount -obind "${DISTDIR}" "${MOUNTPOINT}"/usr/portage/distfiles
|
||||||
|
mount -obind "${PKGDIR}" "${MOUNTPOINT}"/usr/portage/packages
|
||||||
|
mount -t tmpfs tmpfs "${MOUNTPOINT}"/tmp
|
||||||
|
mount -t proc proc "${MOUNTPOINT}"/proc
|
||||||
|
mount -t sysfs sysfs "${MOUNTPOINT}"/sys
|
||||||
|
|
||||||
|
cat <<EOF > "${MOUNTPOINT}"/build-base.sh
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export EMERGE_DEFAULT_OPTS="--binpkg-respect-use=y"
|
||||||
|
export FEATURES="-news"
|
||||||
|
|
||||||
|
env-update
|
||||||
|
USE=-thin emerge -jkv xfsprogs nfs-utils lvm2
|
||||||
|
rc-update add lvm boot
|
||||||
|
EOF
|
||||||
|
chmod u+x "${MOUNTPOINT}"/build-base.sh
|
||||||
|
chroot "${MOUNTPOINT}" /build-base.sh
|
||||||
|
rm "${MOUNTPOINT}"/build-base.sh
|
||||||
|
|
||||||
|
echo "Installing Puppet..."
|
||||||
|
cat <<EOF > "${MOUNTPOINT}"/build-puppet.sh
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export EMERGE_DEFAULT_OPTS="--binpkg-respect-use=y"
|
||||||
|
export FEATURES="-news"
|
||||||
|
|
||||||
|
RUBY_TARGETS=ruby18 USE="-gdbm minimal old-output" emerge -jkv puppet
|
||||||
|
rc-update add puppet default
|
||||||
|
EOF
|
||||||
|
chmod u+x "${MOUNTPOINT}"/build-puppet.sh
|
||||||
|
chroot "${MOUNTPOINT}" /build-puppet.sh
|
||||||
|
rm "${MOUNTPOINT}"/build-puppet.sh
|
||||||
|
|
||||||
|
echo "Configuring Puppet..."
|
||||||
|
cfg_head=$(mktemp)
|
||||||
|
cfg_foot=$(mktemp)
|
||||||
|
awk '/\[agent\]/ {exit} {print}' "${MOUNTPOINT}"/etc/puppet/puppet.conf > ${cfg_head}
|
||||||
|
awk '/\[agent\]/,0' "${MOUNTPOINT}"/etc/puppet/puppet.conf > ${cfg_foot}
|
||||||
|
cat ${cfg_head} > "${MOUNTPOINT}"/etc/puppet/puppet.conf
|
||||||
|
cat <<EOF >> "${MOUNTPOINT}"/etc/puppet/puppet.conf
|
||||||
|
server = ${PUPPETMASTER}
|
||||||
|
pluginsync = true
|
||||||
|
|
||||||
|
EOF
|
||||||
|
cat ${cfg_foot} >> "${MOUNTPOINT}"/etc/puppet/puppet.conf
|
||||||
|
rm ${cfg_head} ${cfg_foot}
|
||||||
|
|
||||||
|
echo "Setting hostname..."
|
||||||
|
sed -i "s/localhost/${VMNAME}/" "${MOUNTPOINT}"/etc/conf.d/hostname
|
||||||
|
|
||||||
|
echo "Configuring network..."
|
||||||
|
echo 'config_eth0="dhcp"' > "${MOUNTPOINT}"/etc/conf.d/net
|
||||||
|
echo 'dhcpcd_eth0="-q"' >> "${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/
|
||||||
|
ln -s /etc/init.d/sshd "${MOUNTPOINT}"/etc/runlevels/default/
|
||||||
|
|
||||||
|
echo "Configuring fstab..."
|
||||||
|
cat << EOF > "${MOUNTPOINT}"/etc/fstab
|
||||||
|
LABEL=root / xfs noatime 0 1
|
||||||
|
LABEL=usr /usr xfs noatime 0 2
|
||||||
|
LABEL=var /var xfs noatime 0 2
|
||||||
|
LABEL=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/mounts "${MOUNTPOINT}"/etc/mtab
|
||||||
|
ln -s /run/resolv.conf "${MOUNTPOINT}"/etc/resolv.conf
|
||||||
|
ln -s /run/ntp.conf "${MOUNTPOINT}"/etc/ntp.conf
|
||||||
|
|
||||||
|
echo "Blanking root password..."
|
||||||
|
sed -i 's/^root:.*/root::0:0:::::/' "${MOUNTPOINT}"/etc/shadow
|
||||||
|
|
||||||
|
echo "Enabling serial console..."
|
||||||
|
sed -i 's/#s0/s0/' "${MOUNTPOINT}"/etc/inittab
|
||||||
|
|
||||||
|
echo "Cleaning up..."
|
||||||
|
umount "${MOUNTPOINT}"/usr/portage/{packages,distfiles,}
|
||||||
|
rmdir "${MOUNTPOINT}"/usr/portage
|
||||||
|
umount "${MOUNTPOINT}"/{tmp,proc,sys,run,usr,var,home,}
|
||||||
|
vgchange -an ${VMNAME}
|
||||||
|
|
||||||
|
echo "Creating libvirt domain..."
|
||||||
|
m4 -P -DNAME="${DOMNAME}" "${DOMXML_TMPL}" | virsh -c qemu:///system define /dev/stdin
|
||||||
|
echo "Starting virtual machine..."
|
||||||
|
virsh -c qemu:///system start ${DOMNAME}
|
Loading…
Reference in New Issue