mirror of
https://git.launchpad.net/livecd-rootfs
synced 2025-02-15 07:08:23 +00:00
patch create_manifest to produce an sbom when called by an ubuntu-cpc project. Patch all the ubuntu-cpc hooks and series files to include the newly generated manifests, filelists, and sboms. Generates a number of new artifacts in the builds. the snap utilized, cpc-sbom, is an open source repo and a provided via a hidden snap. there is no intention of publisizing the snap or how we generate sboms, however partners require the ability to audit if required. defensively checks if the snap is already installed, in the case of multiple hooks being called in a single build (thus sharing a build host), and only if called in an ubuntu-cpc project. (cherry picked from commit 7c7b7df89dc96169db1f255d6bba901ebb63a43c)
258 lines
8.3 KiB
Bash
Executable File
258 lines
8.3 KiB
Bash
Executable File
#!/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
|
|
|
|
create_manifest $mount_d "livecd.ubuntu-cpc.vagrant.manifest" "livecd.ubuntu-cpc.vagrant.spdx" "cloud-image-vagrant-$ARCH-$(date +%Y%m%dT%H:%M:%S)"
|
|
|
|
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##*/}
|