flatcar-scripts/build_sysext
2023-07-05 08:43:25 +02:00

187 lines
5.6 KiB
Bash
Executable File

#!/bin/bash
# Copyright (c) 2023 The Flatcar Maintainers.
# Use of this source code is governed by a BSD-style license that can
# be found in the LICENSE file.
#
# Script to generate sysext. See systemd-sysext(8). Prerequisite is
# that you've run build_packages and build_image.
SCRIPT_ROOT=$(dirname "$(readlink -f "$0")")
. "${SCRIPT_ROOT}/common.sh" || exit 1
# Script must run inside the chroot
assert_inside_chroot
assert_root_user
# All these are used to set up the 'BUILD_DIR' variable
DEFINE_string board "${DEFAULT_BOARD}" \
"The board to build a sysext for."
DEFINE_string build_dir '' \
"Directory used for building the sysext image, must exist, but should be empty."
DEFINE_string metapkgs '' \
"Comma-separated list of meta-packages to build from source and install into sysext image."
DEFINE_string manglefs_script '' \
"A path to executable that will customize the rootfs of the sysext image."
DEFINE_string squashfs_base '' \
"The path to the squashfs base image."
FLAGS_HELP="USAGE: build_sysext [flags] [sysext name] [binary packages to install into image].
This script is used to build a Flatcar sysext image.
Examples:
Builds a sysext image named interpreters in the images
directory with dev-lang/python and dev-lang/perl packages for amd64:
sudo build_sysext \
--board=amd64-usr \
--build_dir=images \
interpreters dev-lang/python dev-lang/perl
Builds a sysext image named oem-azure in the oem-images directory with
metapackage coreos-base/oem-azure for arm64:
sudo build_sysext \
--board=arm64-usr \
--build_dir=oem-images \
--metapkgs=coreos-base/oem-azure \
--mangle_fs=…/coreos-base/oem-azure/files/manglefs.sh \
oem-azure
"
show_help_if_requested "$@"
# Parse command line
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
source "${BUILD_LIBRARY_DIR}/board_options.sh" || exit 1
source "${BUILD_LIBRARY_DIR}/reports_util.sh" || exit 1
if [[ -z "${FLAGS_build_dir}" ]]; then
die "Need a build directory to be specified with a --build_dir option"
fi
BUILD_DIR=$(realpath "${FLAGS_build_dir}")
# Architecture values are taken from systemd.unit(5).
declare -A SYSEXT_ARCHES
SYSEXT_ARCHES['amd64-usr']='x86-64'
SYSEXT_ARCHES['arm64-usr']='arm64'
declare -r SYSEXT_ARCHES
# Usage: _get_sysext_arch board [board...]
_get_sysext_arch() {
local board=${1}
if [[ ${#SYSEXT_ARCHES["${board}"]} -ne 0 ]]; then
echo "${SYSEXT_ARCHES["${board}"]}"
else
die "Unknown board '${board}'"
fi
}
set -euo pipefail
cleanup() {
local dirs=(
"${BUILD_DIR}/fs-root"
"${BUILD_DIR}/install-root"
"${BUILD_DIR}/workdir"
"${BUILD_DIR}/img-rootfs"
)
umount "${dirs[@]}" 2>/dev/null || true
rm -rf "${dirs[@]}" || true
}
if [[ ${#} -lt 1 ]]; then
show_help_if_requested -h
die 'Expected at least one parameter for sysext image name'
fi
SYSEXTNAME="${1}"
shift
# Set up trap to execute cleanup() on script exit
trap cleanup EXIT
ARCH=$(_get_sysext_arch "${FLAGS_board}")
if [[ -z "${FLAGS_squashfs_base}" ]]; then
FLAGS_squashfs_base="${BUILD_DIR}/flatcar_production_image_sysext.squashfs"
fi
cleanup
mkdir "${BUILD_DIR}/fs-root"
mount -rt squashfs -o loop,nodev "${FLAGS_squashfs_base}" "${BUILD_DIR}/fs-root"
mkdir "${BUILD_DIR}/install-root"
mkdir "${BUILD_DIR}/workdir"
mount -t overlay overlay -o lowerdir="${BUILD_DIR}/fs-root",upperdir="${BUILD_DIR}/install-root",workdir="${BUILD_DIR}/workdir" "${BUILD_DIR}/install-root"
VERSION_BOARD=$(grep "^VERSION=" ${BUILD_DIR}/fs-root/usr/lib/os-release | cut -d = -f 2-)
if [ "$VERSION_BOARD" != "$FLATCAR_VERSION" ]; then
echo "$VERSION_BOARD"
echo "$FLATCAR_VERSION"
echo "Version mismatch between board flatcar release and SDK container flatcar release"
exit 1
fi
if [[ -n "${FLAGS_metapkgs}" ]]; then
mapfile -t metapkgs < <(tr ',' '\n' <<<"${FLAGS_metapkgs}")
"emerge-${FLAGS_board}" --nodeps --buildpkgonly --usepkg n --verbose "${metapkgs[@]}"
set -- "${metapkgs[@]}" "${@}"
fi
for package; do
echo "Installing package into sysext image: $package"
FEATURES="-ebuild-locks" emerge \
--root="${BUILD_DIR}/install-root" \
--config-root="/build/${FLAGS_board}" \
--sysroot="/build/${FLAGS_board}" \
--root-deps=rdeps \
--usepkgonly \
--verbose \
"${package}"
done
# Unmount in order to get rid of the overlay
umount "${BUILD_DIR}/install-root"
umount "${BUILD_DIR}/fs-root"
if [[ -n "${FLAGS_manglefs_script}" ]]; then
if [[ ! -x "${FLAGS_manglefs_script}" ]]; then
die "${FLAGS_manglefs_script} is not executable"
fi
"${FLAGS_manglefs_script}" "${BUILD_DIR}/install-root"
fi
info "Removing non-/usr directories from sysext image"
for entry in "${BUILD_DIR}/install-root"/*; do
if [[ "${entry}" = */usr ]]; then
continue
fi
info " Removing ${entry##*/}"
rm -rf "${entry}"
done
mkdir -p "${BUILD_DIR}/install-root/usr/lib/extension-release.d"
version_field="${VERSION_FIELD_OVERRIDE:-VERSION_ID=${FLATCAR_VERSION_ID}}"
all_fields=(
'ID=flatcar'
"${version_field}"
"ARCHITECTURE=${ARCH}"
)
printf '%s\n' "${all_fields[@]}" >"${BUILD_DIR}/install-root/usr/lib/extension-release.d/extension-release.${SYSEXTNAME}"
mksquashfs "${BUILD_DIR}/install-root" "${BUILD_DIR}/${SYSEXTNAME}.raw"
rm -rf "${BUILD_DIR}"/{fs-root,install-root,workdir}
# Generate reports
mkdir "${BUILD_DIR}/img-rootfs"
mount -rt squashfs -o loop,nodev "${BUILD_DIR}/${SYSEXTNAME}.raw" "${BUILD_DIR}/img-rootfs"
write_contents "${BUILD_DIR}/img-rootfs" "${BUILD_DIR}/${SYSEXTNAME}_contents.txt"
write_contents_with_technical_details "${BUILD_DIR}/img-rootfs" "${BUILD_DIR}/${SYSEXTNAME}_contents_wtd.txt"
write_disk_space_usage_in_paths "${BUILD_DIR}/img-rootfs" "${BUILD_DIR}/${SYSEXTNAME}_disk_usage.txt"
umount "${BUILD_DIR}/img-rootfs"