From 2206ce901aa041ce49c667b3110e85b4d752797f Mon Sep 17 00:00:00 2001 From: Barak Korren Date: Mon, 9 Dec 2019 17:02:10 +0200 Subject: [PATCH] base: Support re-baking adn box-only baking Optimised the `bake.sh` script to enable running it on an already baked image to add images to it without adding new copies of existing images. This is done by avoiding deletion of the Vagrant box files and instead making hard-links between the copies of the Vagrant images in the $VAGRANT_HOME directory to the copies in the libvirt storage pool. Also enabled a 'box-only` bake mode that allows creating images that contain cached cipies of Vagrant boxes without also containing pre-configured VMs. This allows creating families of images that contain different VM configurations but all share the layer that contain the large Box image file. Along the way also removed some packages from the base image that caused security alerts to show up in quay.io. Signed-off-by: Barak Korren --- base/Dockerfile | 6 ++-- base/etc/sudoers.d/vagrant | 2 ++ base/sbin/bake.sh | 69 ++++++++++++++++++++++++++++++++------ 3 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 base/etc/sudoers.d/vagrant diff --git a/base/Dockerfile b/base/Dockerfile index 1f2fb3f..a40ef6f 100644 --- a/base/Dockerfile +++ b/base/Dockerfile @@ -15,12 +15,12 @@ RUN \ https://releases.hashicorp.com/vagrant/2.2.6/vagrant_2.2.6_x86_64.rpm \ libvirt-devel ruby-devel gcc libxslt-devel libxml2-devel make \ python3-pip \ - libvirt qemu-kvm rsync openssh-clients \ + libvirt qemu-kvm rsync sudo openssh-clients \ && runuser -u "$VAGRANT_USER" -p -- vagrant plugin install vagrant-libvirt \ && python3 -m pip install dumb-init==1.2.2 \ && yum -y remove \ - libvirt-devel ruby-devel gcc libxslt-devel libxml2-devel make \ - python3-pip \ + libvirt-devel ruby-devel gcc libxslt-devel libxml2-devel \ + python3-pip \*-headers \*-devel \ && yum clean all COPY sbin/ /sbin/ diff --git a/base/etc/sudoers.d/vagrant b/base/etc/sudoers.d/vagrant new file mode 100644 index 0000000..ea7d3ae --- /dev/null +++ b/base/etc/sudoers.d/vagrant @@ -0,0 +1,2 @@ +Defaults:vagrant !requiretty +vagrant ALL = (ALL) NOPASSWD: ALL diff --git a/base/sbin/bake.sh b/base/sbin/bake.sh index dea99dc..7581a54 100755 --- a/base/sbin/bake.sh +++ b/base/sbin/bake.sh @@ -21,26 +21,75 @@ # Note: Since the 80_vagrant_sh.sh entry point runs its arguments as the vagrant # user, this script expects to be running as that user # +# In addition to a path to a Vagrantfile, to following options can be passed to +# this script: +# --box-only - Don't leave configured VMs in the image, only downloaded boxes +# This is useful for making containers with pre-cached images for +# further customization +# +# All other arguments to this script are passed directly to `vagrant up` +# main() { - local vagrant_app_dir="${1:?Path to Vagrant App missing}" + local -a options other_args + local vagrant_app_dir='' box_only='' + parse_args "$@" + + vagrant_app_dir="${vagrant_app_dir:?Path to Vagrant App missing}" if [[ "$vagrant_app_dir" != "$VAGRANT_CWD" ]]; then shopt -s nullglob failglob dotglob - cp -RL -t "$VAGRANT_CWD" "$vagrant_app_dir"/* - chown -R "$VAGRANT_USER:$VAGRANT_USER" "$VAGRANT_CWD" + cp -vRL -t "$VAGRANT_CWD" "$vagrant_app_dir"/* + chown -vR "$VAGRANT_USER:$VAGRANT_USER" "$VAGRANT_CWD" + fi + vagrant_up_down "$box_only" "${options[@]}" "${other_args[@]}" + hardlink_boxes + if [[ $box_only ]] && [[ "$vagrant_app_dir" != "$VAGRANT_CWD" ]]; then + rm -rf "${VAGRANT_CWD:?}"/* fi - vagrant_up_down - clean_boxes +} + +parse_args() { + while [[ $# -gt 0 ]]; do + case "$1" in + --box-only) + box_only=true;; + --) + shift; break;; + -.*) + options+="$1";; + *) + vagrant_app_dir="$1"; shift; break;; + esac + shift + done + other_args=("$@") } vagrant_up_down() { - vagrant up + local box_only="${1?:}" + shift + + # we don't want to quote here on purpose so we don't pass an empty string + # when 'box_only' is blank (false) + # shellcheck disable=2086 + vagrant up ${box_only:+--no-provision} "$@" vagrant halt + if [[ $box_only ]]; then + vagrant destroy -f + fi } -clean_boxes() { - vagrant box list --machine-readable \ - | sed -nre 's/^[0-9]+,,box-name,(.*)$/\1/p' \ - | xargs -rn 1 vagrant box remove -f --all +hardlink_boxes() { + # Ensure all boxes can be read by the qemu user + # Note: we must not run chown or chmod on any files that do not need it + # because if causes overlayfs2 to copy the file even is the mode/owner is + # not actually changed + find "$VAGRANT_HOME/boxes" -type f -name \*.img \! -perm 444 -print0 \ + | xargs -0 -r sudo -n chmod -v 444 + find "$VAGRANT_HOME/boxes" -type f -name \*.img \ + \! \( -user qemu -group qemu \) -print0 \ + | xargs -0 -r sudo -n chown -v qemu:qemu + # Hardlink boxes to the copies in the libvirt pool + sudo -n hardlink -c -vv /var/lib/libvirt/images "$VAGRANT_HOME/boxes" } if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then