Skip to content

Instantly share code, notes, and snippets.

@griznog
Created August 24, 2023 13:48
Show Gist options
  • Save griznog/0405b1d864d9e74ddb642f56f137a4d1 to your computer and use it in GitHub Desktop.
Save griznog/0405b1d864d9e74ddb642f56f137a4d1 to your computer and use it in GitHub Desktop.
Wrapper for building all overlays.
#!/bin/bash
# Author: griznog
# Purpose: Build/update overlays for all nodes.
# Pull in warewulf functions/variables for this node.
[[ -f /warewulf/etc/functions ]] && source /warewulf/etc/functions || exit 1
# Collect an MD5SUM for an entire directory, hopefully in a repeatable way.
function wwovl_md5sum () {
local ovl=$1
# Abort early if the overlay doesn't actually exist.
[[ -d ${WWOVERLAYDIR}/${ovl} ]] || return 1
cat $(find ${WWOVERLAYDIR}/${ovl} -type f ! -iname ".wwovl_${ovl}_version") | md5sum
}
# Detect changes to the overlay.
function is_overlay_changed () {
local ovl=$1
local retval=0 # Assume yes.
local MD5SUMFILE=${ovl}/MD5SUM
local VERSIONFILE=${ovl}/rootfs/.wwovl_${ovl}_version
# Abort early if the overlay doesn't actually exist and use rootfs directory for content.
[[ -d ${WWOVERLAYDIR}/${ovl}/rootfs ]] || return 1
# Get previous checksum, seeding the files if not found.
if [[ -f ${MD5SUMFILE} ]]; then
local MD5SUM_OLD=$(<${MD5SUMFILE})
else
local MD5SUM_OLD=( $(cat $(find ${ovl}/rootfs -type f ! -iname .wwovl_${ovl}_version | sort) | md5sum ) )
echo echo ${MD5SUM_OLD[0]} > ${MD5SUMFILE}
fi
# Get previous version, seedin the version file if not found.
if [[ -f ${VERSIONFILE} ]]; then
local VERSION_OLD=$(<${VERSIONFILE})
else
local VERSION_OLD=0
echo ${VERSION_OLD} > ${VERSIONFILE}
fi
# Collect a current md5sum for the overlay.
local MD5SUM_NEW=( $(cat $(find ${ovl}/rootfs -type f ! -iname .wwovl_${ovl}_version | sort) | md5sum ) )
# See if version needs to increment.
if [[ "${MD5SUM_OLD}" != "${MD5SUM_NEW[0]}" ]]; then
# There were changes, increment the version and rebuild
local VERSION_NEW=$(( ${VERSION_OLD} + 1 ))
echo ${VERSION_NEW} > ${VERSIONFILE}
echo ${MD5SUM_NEW[0]} > ${MD5SUMFILE}
retval=0
else
# There were no detected changes.
retval=1
fi
return ${retval}
}
function build_overlay () {
local ovl=$1
local force=$2
local retval=0
local MD5SUMFILE=${ovl}/MD5SUM
local VERSIONFILE=${ovl}/rootfs/.wwovl_${ovl}_version
if [[ -d ${WWOVERLAYDIR}/${ovl}/rootfs ]]; then
if is_overlay_changed ${ovl} || [[ -n ${force} ]]; then
wwctl overlay build -O ${ovl} > /dev/null 2>&1
retval=$?
echo " ${ovl}: Built version $(<${VERSIONFILE})"
else
echo " ${ovl}: No changes detected, skipping build."
fi
else
echo " ${ovl} has no rootfs directory, skipping build."
retval=1
fi
return ${retval}
}
# Script starts here
# Find the overlay root location.
WWCONF=/etc/warewulf/warewulf.conf # Yeah, hard coded. But we have to start somewhere.
[[ -f ${WWCONF} ]] || \
die "Can't find ${WWCONF}"
# See https://github.com/hpcng/warewulf/issues/635 as I'm pretending like that has
# already been added to WW4.
WWOVERLAYDIR=$(yq ".paths.overlays" < /etc/warewulf/warewulf.conf)
# Overlays are complicated. Do this in steps.
# First, move to overlay directory.
pushd ${WWOVERLAYDIR} > /dev/null 2>&1 || \
die "Could not find overlay directory: ${WWOVERLAYDIR}"
# Third, the 'wwctl overlay build' command still has some quirks. We need
# it to build individually to be able to do live updates for specific overlays.
echo "Building standalone overlays..."
force=''; [[ "$*" =~ .*force.* ]] && force=force
for ovl in *; do
# [[ ${ovl} =~ ^system ]] && continue
# Build the overlay.
build_overlay ${ovl} ${force} &
done # | sort
wait
echo "... completed building individual overlays."
echo
popd > /dev/null 2>&1
# Last, build the merged overlay image used for booting.
if [[ "$*" =~ "merged" ]]; then
echo -n "Building merged overlays for node booting..."
wwctl overlay build > /dev/null 2>&1
echo "...done."
else
echo "Use '$(basename $0) --merged' to also build merged overlays for initrd."
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment