In an earlier post, I wrote about installing Vagrant Guest Additions in a Debian Stretch distribution.
Here is a script, which needs to be run as root inside the guest to be used as the Vagrant package base, which will perform the necessary changes. For running with Linux kernel 4.8 or later, VirtualBox 5.1.8 or later will be required.
The command line takes one parameter... the target VirtualBox version, which at the time of this writing, is 5.1.8. This example would be run as root with (if the code is in a file called additions.sh):
bash additions.sh 5.1.8
The script takes care of obtaining the GuestAdditions iso, installing related packages, building the additions, removing the packages, and zeroing out dead disk space. This makes it ready for the second script which will generate the package.box.
#! /usr/bin/bash
function cleanup {
# package clean up
apt-get autoremove
apt-get purge
apt-get clean
apt-get autoclean
# remove indexes
rm /var/lib/apt/lists/*
# todo: look at /lib/modules when kernel upgraded
# zero out unused space for more efficient packing
echo "Zeroing out dead space ..."
dd if=/dev/zero of=/EMPTY bs=1M
rm -f /EMPTY
}
function vagrantuser {
# sudo settings
cat <> /etc/sudoers.d/10-sudo-overrides
Defaults env_keep += "GIT_*"
Defaults>root env_keep += SSH_AUTH_SOCK
Defaults>root !requiretty
%sudo ALL=NOPASSWD: ALL
EOT
# default vagrant key for bootstrapping
echo "Installing default key ...."
mkdir /home/vagrant/.ssh
chmod 700 /home/vagrant/.ssh
pushd /home/vagrant/.ssh
wget --no-check-certificate \
'https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub' \
-O authorized_keys
chmod 600 /home/vagrant/.ssh/authorized_keys
chown -R vagrant /home/vagrant/.ssh
popd
}
function guestadditions {
VBOXVER="$1"
# obtain and mount the VBoxGuestAdditions iso
echo "Obtaining Guest Additions ..."
wget \
http://download.virtualbox.org/virtualbox/${VBOXVER}/VBoxGuestAdditions_${VBOXVER}.iso
mkdir /media/VBoxGuestAdditions
mount -o loop,ro VBoxGuestAdditions_${VBOXVER}.iso /media/VBoxGuestAdditions
# build the additions
echo "Building additions ..."
KERN_DIR=/usr/src/linux-headers-$(uname -r)/ \
sh /media/VBoxGuestAdditions/VBoxLinuxAdditions.run
# unmount and remove the iso
echo "Building done, unmount iso ..."
umount /media/VBoxGuestAdditions
rmdir /media/VBoxGuestAdditions
rm VBoxGuestAdditions_${VBOXVER}.iso
}
function build {
VBOXVER="$1"
echo "sources: "
cat /etc/apt/sources.list | awk '/^deb/ {print $0}'
# sudo and ssh key are one time settings
if [[ "" == "$(ls -d /usr/src/vbox*)" ]]; then
vagrantuser
fi
# install build tools for the VirtualBox Guest Additions, required for Vagrant
echo "Installing packages ..."
apt-get update
PACKAGES=$(apt-get -y install linux-headers-$(uname -r) build-essential | awk \
'BEGIN { flag=0; list="" } \
/^[^ ]/ { flag=0 } \
/NEW packages will be installed/ { flag=1 } \
/ / { if (1 == flag) list=list$0 } \
END { print list }' \
)
echo "Installed packages: ${PACKAGES}"
guestadditions ${VBOXVER}
# remove packages
echo "Removing packages and cleaning up ..."
apt-get -y remove ${PACKAGES}
apt-get -y remove linux-headers-$(uname -r)
# add in some commonly used packages
apt-get -y install less tcpdump vim
cleanup
# show guest stuff installed
ls -alt /usr/src
df -h
IMAGECNT=$(dpkg -l | grep linux-image | wc -l)
if [ "1" != "${IMAGECNT}" ]; then
echo "More than one image installed, remove excess to reclaim space"
dpkg -l | grep linux-image
fi
}
if [ "root" != $(whoami) ]; then
echo "need to be user root"
else
if [ "" == "$1" ]; then
echo "[virtualbox version code (like 5.1.
| clean]"
else
case "$1" in
clean)
cleanup
;;
*)
build $1
;;
esac
fi
fi
Ensure the VirtualBox guest network interface #1 is NAT with para-virtualized IO. And verify the CD is removed.
Here is a script to run to pack a VirtualBox VM/Template into a box file for use by Vagrant (after the above script has been applied inside of the guest). On Windows, I run it in a cygwin environment. On Linux, it can be run natively.
#! /usr/bin/bash
# $1 - source base name
# $2 - packaged box name
if [ 2 != $# ]; then
echo "two arguments: VirtualBoxVMName PackagedBoxName"
else
VIRTUALBOXNAME=$1
PACKAGEDNAME=$2
# create a basic description file
cat <<EOT >> ${PACKAGEDNAME}.vf
Vagrant::Config.run do |config|
config.ssh.username = "vagrant"
end
EOT
# package up the guest
vagrant package --base ${VIRTUALBOXNAME} --vagrantfile ${PACKAGEDNAME}.vf
if [[ ! -d boxes ]]; then
mkdir boxes
fi
if [[ -e boxes/${PACKAGEDNAME}.box ]]; then
rm boxes/${PACKAGEDNAME}.box
fi
mv package.box boxes/${PACKAGEDNAME}.box
rm ${PACKAGEDNAME}.vf
fi


