Select Git revision
update-vmine-images.sh
Forked from
pipelines / tools / vmine
Source project has a limited visibility.
update-vmine-images.sh 4.55 KiB
#!/bin/sh
#
# Manage a mirror of the pre-built vmine images.
#
base_url="https://git.autistici.org/api/v4/projects/493"
target_dir="/var/lib/vmine/images"
registry_path="/etc/vmine/images.yml"
images="buster/10.9.0 bullseye/11.0.0"
default_image="buster"
op="download"
usage() {
cat <<EOF
Usage: $0 [<options>]
Update locally stored VMine images, either by downloading them or
building them.
The tool will update the image files, and rewrite the VMine image
registry with the new paths, in such a way so as not to disturb the
ongoing operations of the vmine server.
The image registry file will be fully rewritten and any manual edits
will be lost.
Options:
--datadir=PATH Path for images (default "${target_dir}")
--registry-file=PATH Location of the image registry (default "${registry_path}")
--images=SPEC Which images to build, a space-separated list of
DISTRO/VERSION pairs (default "${images}")
--default-image=NAME Name (distro) of the default image
--download Download pre-built images
--build Build images using autopkgtest-build-qemu
EOF
exit 2
}
while [ $# -gt 0 ]; do
case "$1" in
--datadir=*) target_dir="${1#*=}" ;;
--datadir) target_dir="$2" ; shift ;;
--registry-file=*) registry_path="${1#*=}" ;;
--registry-file) registry_path="$2" ; shift ;;
--images=*) images="${1#*=}" ;;
--images) images="$2" ; shift ;;
--default-image=*) default_image="${1#*=}" ;;
--default-image) default_image="$2" ; shift ;;
--download) op=download ;;
--build) op=build ;;
--help) usage ;;
*) echo "Unknown argument '$1'" >&2 ; usage ;;
esac
shift
done
# We intend to update the configuration without it ever being invalid,
# so we don't have to coordinate with the vmine server process.
#
# So, for every image, we use a timestamped directory to build the
# image, and delete the previous one only after having successfully
# generated a new registry file.
#
# If at any point we fail, all the generated files will be deleted.
# Accumulate generated files in tmp_dirs.
tmp_dirs=
tmp_registry=$(mktemp)
trap "[ -n \"$tmp_dirs\" ] && rm -fr ${tmp_dirs} 2>/dev/null ; rm -f ${tmp_registry} 2>/dev/null" EXIT TERM INT
emit_image() {
local image_name="$1"
local image_path="$(realpath "$2")"
local kernel_path="$(echo ${image_path}/vmlinuz*)"
local initrd_path="$(echo ${image_path}/initrd*)"
cat >>${tmp_registry} <<EOF
${image_name}:
path: "${image_path}/rootfs.img"
kernel_path: "${kernel_path}"
initrd_path: "${initrd_path}"
EOF
}
atomic_registry_update() {
echo "---" > ${tmp_registry}
echo "default: ${default_image}" >> ${tmp_registry}
echo "images:" >> ${tmp_registry}
"$@" || exit 1
mv -f ${tmp_registry} ${registry_path} \
|| exit 1
}
build_image() {
local distro="${1%/*}"
local build_dir="$2"
echo
echo "*** Building image '${img}'"
echo
autopkgtest-build-qemu \
${distro} \
${build_dir}/rootfs.img \
http://deb.debian.org/debian \
amd64 \
/usr/lib/vmine/post-install.sh \
|| exit 1
/usr/lib/vmine/extract-kernel.sh \
${build_dir}/rootfs.img \
${build_dir} \
|| exit 1
}
download_image() {
local image_and_version="$1"
local build_dir="$2"
local distro="${image_and_version%/*}"
local url="${base_url}/packages/generic/${image_and_version}/${distro}.tar"
echo "downloading and unpacking ${url}"
curl -s "${url}" \
| tar -C "${build_dir}" -x -f - \
|| exit 1
}
update_images() {
for img in ${images}; do
# Create a new timestamped dir for the image, and mark the
# previous ones (for this same distribution) for deletion.
base_img_dir="${target_dir}/${img%/*}"
build_dir="${base_img_dir}/$(date +%s)"
tmp_dirs="${tmp_dirs} ${build_dir}"
old_build_dirs="${old_build_dirs} $(find ${base_img_dir} -mindepth 1 -maxdepth 1 -type d 2>/dev/null)"
mkdir -p ${build_dir} \
|| exit 1
${op}_image "${img}" "${build_dir}"
emit_image "${img%/*}" "${build_dir}"
done
}
atomic_registry_update update_images
# If everything went ok we can remove the old dirs.
for old_dir in ${old_build_dirs}; do
if [ -d ${old_dir} ]; then
echo "removing old directory ${old_dir}"
rm -fr ${old_dir}
fi
done
# Reload the vmine service.
systemctl reload vmine.service
exit 0