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