You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
256 lines
8.1 KiB
256 lines
8.1 KiB
#!/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 ${SUBPROJECT:-} in
|
|
minimized)
|
|
echo "Skipping minimized $0 build as images won't boot with linux-kvm"
|
|
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 ;;
|
|
*)
|
|
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
|
|
|
|
|
|
##########################
|
|
### Vagrant User Setup
|
|
### Create ed25519 ssh key
|
|
### the default insecure key is rsa, and that is disabled in Jammy forward
|
|
### https://github.com/hashicorp/vagrant/tree/main/keys
|
|
##########################
|
|
|
|
ssh-keygen -t ed25519 -C "ubuntu_vagrant_insecure_key" -b 4096 \
|
|
-f ${box_d}/vagrant_insecure_key -N ""
|
|
|
|
pub_key=$(cat ${box_d}/vagrant_insecure_key.pub)
|
|
|
|
# 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
|
|
# Note: We decided NOT to allow root login with a default password.
|
|
chroot ${mount_d} adduser vagrant --disabled-password --gecos ""
|
|
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
|
|
|
|
# Add an 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
|
|
cat << EOF > ${mount_d}/home/vagrant/.ssh/authorized_keys
|
|
${pub_key}
|
|
EOF
|
|
chroot ${mount_d} chown -R vagrant:vagrant /home/vagrant/.ssh
|
|
chroot ${mount_d} chmod 700 /home/vagrant/.ssh
|
|
|
|
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} 40960
|
|
|
|
####################################
|
|
# 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 <<END
|
|
#cloud-config
|
|
manage_etc_hosts: localhost
|
|
END
|
|
|
|
# Create the fake meta-data
|
|
cat > ${seed_d}/meta-data <<END
|
|
instance-id: iid-$(openssl rand -hex 8)
|
|
local-hostname: ubuntu-${suite}
|
|
END
|
|
|
|
# Pad the cdrom, otherwise the VMDK will be invalid
|
|
dd if=/dev/zero of=${seed_d}/bloat_file bs=1M count=10
|
|
|
|
# Create the ISO
|
|
genisoimage \
|
|
-output ${seed_d}/seed.iso \
|
|
-volid cidata \
|
|
-joliet -rock \
|
|
-input-charset utf-8 \
|
|
${seed_d}/user-data \
|
|
${seed_d}/meta-data
|
|
|
|
# Make a VMDK out of the seed file.
|
|
create_vmdk ${seed_d}/seed.iso ${cdrom_vmdk_f} 10
|
|
|
|
### END Create ConfigDrive
|
|
|
|
##########################
|
|
# VAGRANT meta-data
|
|
|
|
# Create the Vagrant file. This file is used by Vagrant to define how
|
|
# Vagrant uses Virtualbox and how Vagrant interacts with the host.
|
|
macaddr="02$(openssl rand -hex 5 | tr [:lower:] [:upper:])"
|
|
cat > ${box_d}/Vagrantfile <<EOF
|
|
# Front load the includes
|
|
include_vagrantfile = File.expand_path("../include/_Vagrantfile", __FILE__)
|
|
load include_vagrantfile if File.exist?(include_vagrantfile)
|
|
|
|
Vagrant.configure("2") do |config|
|
|
config.vm.base_mac = "${macaddr}"
|
|
# Set to use our vagrant_insecure_key. Path is relative to Vagrantfile
|
|
config.ssh.private_key_path = File.join(File.expand_path(File.dirname(__FILE__)), "vagrant_insecure_key")
|
|
|
|
config.vm.provider "virtualbox" do |vb|
|
|
vb.customize [ "modifyvm", :id, "--uart1", "0x3F8", "4" ]
|
|
# Create a NULL serial port to skip console logging by default
|
|
vb.customize [ "modifyvm", :id, "--uartmode1", "file", File::NULL ]
|
|
# If console logging is desired, uncomment this line and remove prior
|
|
# vb.customize [ "modifyvm", :id, "--uartmode1", "file", File.join(Dir.pwd, "${prefix}-console.log") ]
|
|
# Ubuntu cloud images, by default, enable console=ttyS0. This enables serial consoles to
|
|
# connect to the images. With the change related to LP #1777827, removing a serial
|
|
# file logger, Vagrant image boot times increased and now run greater than 5 minutes
|
|
# Creating a console log file is not an expected default behavior for vagrant boxes.
|
|
# As a workaround, we create a console connection to File:NULL. LP #1874453
|
|
# This is overrideable in user files to write to a local file
|
|
end
|
|
end
|
|
EOF
|
|
|
|
# Tag it as a Virtualbox Vagrant
|
|
cat > ${box_d}/metadata.json <<EOF
|
|
{
|
|
"provider": "virtualbox"
|
|
}
|
|
EOF
|
|
|
|
# END
|
|
##########################
|
|
|
|
##########################
|
|
# Create the actual box
|
|
|
|
# Get information about the disks for the OVF
|
|
vmdk_size=$(du -b "${vmdk_f}" | cut -f1)
|
|
vmdk_capacity=$(qemu-img info "${vmdk_f}" | awk '-F[\( ]' '$1 ~ /virtual/ && $NF ~ /bytes.*/ {print$(NF-1)}')
|
|
vmdk_sha256=$(sha256sum ${vmdk_f} | cut -d' ' -f1)
|
|
|
|
cdrom_size=$(du -b "${cdrom_vmdk_f}" | cut -f1)
|
|
cdrom_capacity=$(qemu-img info "${cdrom_vmdk_f}" | awk '-F[\( ]' '$1 ~ /virtual/ && $NF ~ /bytes.*/ {print$(NF-1)}')
|
|
cdrom_sha256=$(sha256sum ${cdrom_vmdk_f} | cut -d' ' -f1)
|
|
|
|
# Populate the OVF template
|
|
ovf="${box_d}/box.ovf"
|
|
cp ${my_d}/ovf/ubuntu-ova-v1-cloudcfg-vmdk.tmpl ${ovf}
|
|
serial_stamp=$(date +%Y%m%d)
|
|
sed -i "${ovf}" \
|
|
-e "s/@@NAME@@/${prefix}-${serial_stamp}/g" \
|
|
-e "s/@@FILENAME1@@/${vmdk_f##*/}/g" \
|
|
-e "s/@@VMDK_FILE_SIZE@@/${vmdk_size}/g" \
|
|
-e "s/@@VMDK_CAPACITY@@/${vmdk_capacity}/g" \
|
|
-e "s/@@FILENAME2@@/${cdrom_vmdk_f##*/}/g" \
|
|
-e "s/@@VMDK_FILE_SIZE2@@/${cdrom_size}/g" \
|
|
-e "s/@@VMDK_CAPACITY2@@/${cdrom_capacity}/g" \
|
|
-e "s/@@NUM_CPUS@@/2/g" \
|
|
-e "s/@@VERSION@@/${version}/g" \
|
|
-e "s/@@DATE@@/${serial_stamp}/g" \
|
|
-e "s/@@MEM_SIZE@@/1024/g" \
|
|
-e "s/@@OVF_ID@@/${ovf_id}/g" \
|
|
-e "s/@@OVF_OS_TYPE@@/${ovf_os_type}/g" \
|
|
-e "s/@@OVF_DESC_BITS@@/${ovf_desc_bits}/g"
|
|
|
|
ovf_sha256=$(sha256sum ${ovf} | cut -d' ' -f1)
|
|
|
|
# Generate the manifest
|
|
manifest="${box_d}/${prefix}.mf"
|
|
cat > "${manifest}" <<EOF
|
|
SHA256(${vmdk_f##*/})= ${vmdk_sha256}
|
|
SHA256(${cdrom_vmdk_f##*/})= ${cdrom_sha256}
|
|
SHA256(${ovf##*/})= ${ovf_sha256}
|
|
EOF
|
|
|
|
# Now create the box
|
|
echo "Creating OVA with the following attributes:"
|
|
cat <<EOM
|
|
OVA information:
|
|
Name: ${prefix}
|
|
Size: ${vmdk_size}
|
|
VMDK Name: ${vmdk_f##*/}
|
|
VMDK Capacity: ${vmdk_capacity}
|
|
VMDK SHA256: ${vmdk_sha256}
|
|
CDROM Name: ${cdrom_vmdk_f##*/}
|
|
CDROM Capacity: ${cdrom_capacity}
|
|
CDROM SHA256: ${cdrom_sha256}
|
|
EOM
|
|
|
|
tar -C ${box_d} \
|
|
--sort=name \
|
|
-cf ${cur_d}/livecd.ubuntu-cpc.vagrant.box \
|
|
box.ovf \
|
|
Vagrantfile \
|
|
vagrant_insecure_key \
|
|
vagrant_insecure_key.pub \
|
|
metadata.json \
|
|
${prefix}.mf \
|
|
${vmdk_f##*/} \
|
|
${cdrom_vmdk_f##*/}
|