163 lines
5.2 KiB
Bash
Executable File
163 lines
5.2 KiB
Bash
Executable File
#!/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)"
|
|
|
|
if [[ -z $STAGE_TBZ || -z $VMNAME ]]; then
|
|
echo "Usage: $(basename $0) <vmname> <stage3-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"}
|
|
|
|
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}
|
|
|
|
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}"
|
|
|
|
cp -L /etc/resolv.conf "${MOUNTPOINT}/etc/resolv.conf"
|
|
|
|
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 buildpkg"
|
|
|
|
env-update
|
|
USE=-thin emerge -jkv xfsprogs nfs-utils lvm2 distcc iproute2 acpid
|
|
rc-update add lvm boot
|
|
rc-update add acpid default
|
|
rc-update add nfsmount default
|
|
EOF
|
|
chmod u+x "${MOUNTPOINT}"/build-base.sh
|
|
chroot "${MOUNTPOINT}" /build-base.sh
|
|
rm "${MOUNTPOINT}"/build-base.sh
|
|
|
|
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
|
|
|
|
atria:/portage/tree /var/cache/portage/tree nfs4 soft,bg,intr,ro 0 0
|
|
atria:/portage/distfiles /var/cache/portage/distfiles nfs4 soft,bg,intr 0 0
|
|
atria:/portage/binpkgs /var/cache/portage/binpkgs nfs4 soft,bg,intr 0 0
|
|
EOF
|
|
|
|
echo "Configuring Portage..."
|
|
mkdir -p "${MOUNTPOINT}"/var/cache/portage/{tree,distfiles,binpkgs}
|
|
ln -snf ../../var/cache/portage/tree/profiles/"${PORTAGE_PROFILE}" \
|
|
"${MOUNTPOINT}"/etc/portage/make.profile
|
|
cat <<"EOF" > "${MOUNTPOINT}"/etc/portage/make.conf
|
|
CFLAGS="-O2 -pipe -march=amdfam10 -mtune=amdfam10 -mcx16 -msahf -mpopcnt -mabm
|
|
--param l1-cache-size=64 --param l1-cache-line-size=64
|
|
--param l2-cache-size=512"
|
|
CXXFLAGS="${CFLAGS}"
|
|
PORTDIR="/var/cache/portage/tree"
|
|
DISTDIR="/var/cache/portage/distfiles"
|
|
PKGDIR="/var/cache/portage/binpkgs/default-linux/amd64/amdfam10"
|
|
EMERGE_DEFAULT_OPTS="--usepkg --jobs --load-average=3"
|
|
FEATURES="distcc-pump distcc buildpkg"
|
|
MAKEOPTS="-j9"
|
|
USE="3dnow 3dnowext -X -berkdb -gdbm kerberos mmx mmxext sse sse2"
|
|
EOF
|
|
cat <<EOF > "${MOUNTPOINT}"/etc/distcc/hosts
|
|
atria,cpp,lzo
|
|
seginus-x1,cpp,lzo
|
|
betaindi,cpp,lzo
|
|
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..."
|
|
virsh -c qemu:///system define <(m4 -P -DNAME="${DOMNAME}" "${DOMXML_TMPL}")
|
|
echo "Starting virtual machine..."
|
|
virsh -c qemu:///system start ${DOMNAME}
|