#!/bin/bash -ex # vi: ts=4 noexpandtab # # Generate a generic Vagrant Box. # # Vagrant images are essentially nothing more than OVA's with extra-metadata # and some preinstalled packages. # # We can't use the OVA's for Vagrant since Vagrant uses SSH to modify the # instance. This build step creates a cloud-config ISO so that Cloud-Init # will configure the initial user, creates meta-data that tells Vagrant how # to interact with the cloud-init created users, and finally create the OVA. # # For this step, we make a deriviative of binary/boot/disk.ext4 and install # some packages in it, convert it to a vmdk, and then assemble the vagrant # box. case $IMAGE_TARGETS in ""|*vagrant*) ;; *) echo "Skipping Vagrant image build" exit 0 ;; esac cur_d=${PWD} my_d=$(dirname $(readlink -f ${0})) # Switch on $ARCH to determine which ID and description to use in the produced # OVF. We have fancy Ubuntu-specific IDs in the OVF specification, we might as # well use them. case $ARCH in amd64) ovf_id=94 ovf_os_type="ubuntu64Guest" ovf_desc_bits=64 ;; i386) ovf_id=93 ovf_os_type="ubuntu32Guest" ovf_desc_bits=32 ;; *) echo "Vagrant images are not supported for $ARCH yet." exit 0;; esac . config/functions # Lets be safe about this box_d=$(mktemp -d) seed_d=$(mktemp -d) mount_d=$(mktemp -d) create_derivative "disk" "vagrant" #sets ${derivative_img} mount_disk_image ${derivative_img} ${mount_d} cleanup_vagrant() { if [ -d "$mount_d" ]; then umount_disk_image "$mount_d" fi rm -rf ${box_d} ${seed_d} ${mount_d} ${derivative_img} } trap cleanup_vagrant EXIT chroot ${mount_d} apt-get update # virtualbox-guest-utils Recommends: virtualbox-guest-x11, which we want to # avoid pulling into a cloud image. chroot ${mount_d} apt-get install --no-install-recommends -y virtualbox-guest-utils chroot ${mount_d} apt-get clean # Create and setup users inside the image. # Vagrant users expect a "vagrant" user with a "vagrant" username. # See https://www.vagrantup.com/docs/boxes/base.html chroot ${mount_d} useradd -m vagrant -s /bin/bash echo "vagrant:vagrant" | chroot ${mount_d} chpasswd # The vagrant user should have passwordless sudo. cat << EOF > ${mount_d}/etc/sudoers.d/vagrant vagrant ALL=(ALL) NOPASSWD:ALL EOF # We should permit root login with password :( #sed -i 's/^#PermitRootLogin .*/PermitRootLogin yes/g' ${mount_d}/etc/ssh/sshd_config # Add the insecure vagrant pubkey to the vagrant user, as is expected by the # vagrant ecosystem (https://www.vagrantup.com/docs/boxes/base.html) chroot ${mount_d} chmod 0440 /etc/sudoers.d/vagrant chroot ${mount_d} mkdir -p /home/vagrant/.ssh chroot ${mount_d} chown -R vagrant: /home/vagrant/.ssh cat << EOF > ${mount_d}/home/vagrant/.ssh/authorized_keys ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key EOF umount_disk_image "$mount_d" rmdir "$mount_d" # Used to identify bits suite=$(chroot chroot lsb_release -c -s) version=$(chroot chroot lsb_release --release --short) distro=$(chroot chroot lsb_release --id --short | tr [:upper:] [:lower:]) # Get the VMDK in place prefix="${distro}-${suite}-${version}-cloudimg" vmdk_f="${box_d}/${prefix}.vmdk" create_vmdk ${derivative_img} ${vmdk_f} # Vagrant needs a base user. We either inject the well-known SSH key # or use password authentication. Both are ugly. So we'll use a password # and make it random. This obviously is insecure...but at least its # better than the alternatives. ubuntu_user_pass=$(openssl rand -hex 12) #################################### # Create the ConfigDrive # This is a cloud-init piece that instructs cloud-init to configure # a default user at first boot. cdrom_vmdk_f="${box_d}/${prefix}-configdrive.vmdk" # Create the user-data. This is totally insecure, but so is Vagrant. To # mitigate this insecurity, the vagrant instance is not accessible # except via local host. cat > ${seed_d}/user-data < ${seed_d}/meta-data < ${box_d}/Vagrantfile < ${box_d}/metadata.json < "${manifest}" <