#!/bin/bash## kola:## # Marked as exclusive as we layer content over /usr with sysexts## exclusive: true## # Limited to FCOS for now as we don't have easy access to repos on RHCOS## distros: fcos## # Limited to x86_64 & aarch64 for now (see inline TODO)## architectures: "x86_64 aarch64"## # Should work the same on all platforms## # Needs internet access to download RPMs to build sysexts## tags: "platform-independent needs-internet"## description: Verify building, setting up and enabling systemd system extensions (sysexts)set -xeuo pipefail# shellcheck disable=SC1091. "$KOLA_EXT_DATA/commonlib.sh"# Install tools that we need to build the sysextsrpm-ostree install -y --apply-live erofs-utils lz4build_sysext(){local -r rpm="${1}"tmpdir="/tmp/sysext-${rpm}"mkdir "${tmpdir}"pushd "${tmpdir}" > /dev/nullmkdir -p "rpms"pushd "rpms" > /dev/null# Download RPMs:# - Resolve dependency relative to the current root# - Only get packages for the current arch and arch independent ones# - Disable the OpenH264 repo as it's a frequent source of flakesprintf "[main]\nskip_system_repo_lock=true" > dnf_configdnf download \--config=dnf_config \--resolve \--arch="noarch" \--arch="$(arch)" \--disablerepo=fedora-cisco-openh264 \"${rpm}"# Figure out version to usepkg="$(ls ${rpm}-*.rpm | sort -h | head -1)"epoch="$(rpm -qp --queryformat '%{EPOCH}' ${pkg})"version="$(rpm -qp --queryformat '%{VERSION}-%{RELEASE}' ${pkg})"if [[ "${epoch}" == "(none)" ]]; thenepoch=""elseepoch="${epoch}-"fiversion="${epoch}${version}"popd > /dev/nullmkdir rootfspushd rootfs > /dev/null# Post process architecture to match systemd architecture list# TODO: Figure out the mapping for other architecturesif [[ "$(arch)" == "x86_64" ]]; thenarch="x86-64"elif [[ "$(arch)" == "aarch64" ]]; thenarch="arm64"elseecho "Unsupported architecture"exit 1fiid="$(source /etc/os-release; echo "${ID}")"version_id="$(source /etc/os-release; echo "${VERSION_ID}")"# Write extension config fileinstall -d -m0755 usr/lib/extension-release.d{echo "ID=\"${id}\""echo "VERSION_ID=\"${version_id}\""echo "ARCHITECTURE=\"${arch}\""} | tee "usr/lib/extension-release.d/extension-release.${rpm}"# Extract the RPMsfor r in ../rpms/*.rpm; doecho "Extracting: $(basename ${r})"rpm2cpio "${r}" > ${r}.tarcpio -idmv &> /dev/null < ${r}.tarrm ${r}.tardone# Reset SELinux labelsfilecontexts="/etc/selinux/targeted/contexts/files/file_contexts"setfiles -r . ${filecontexts} . && chcon --user=system_u --recursive .popd > /dev/null# Create the EROFS imagename="${rpm}-${version}-${version_id}-${arch}.raw"mkfs.erofs -zlz4 "${name}" rootfsmv "${name}" /tmppopd > /dev/null}build_sysext "python3"# Setup foldersinstall -d -m 0755 -o 0 -g 0 /var/lib/extensions /var/lib/extensions.drestorecon -RFv /var/lib/extensions /var/lib/extensions.dsystemctl enable --now systemd-sysext.serviceinstall_sysext() {local -r name="${1}"mv "/tmp/${name}"*".raw" "/var/lib/extensions.d"ln -snf "/var/lib/extensions.d/${name}"*".raw" "/var/lib/extensions/${name}.raw"restorecon -RFv "/var/lib/extensions.d" "/var/lib/extensions"}install_sysext python3systemctl restart systemd-sysext.servicesystemd-sysext statusif [[ ! -f "/usr/bin/python3" ]]; thenfatal "python3 binary not found but sysext enabled"fiif [[ "$(/usr/bin/python3 -c 'print("python3-on-fcos-via-sysext")')" != "python3-on-fcos-via-sysext" ]]; thenfatal "could not execute simple Python command"fiuninstall_sysext() {local -r name="${1}"rm "/var/lib/extensions/${name}.raw"rm "/var/lib/extensions.d/${name}-"*".raw"}uninstall_sysext python3systemctl restart systemd-sysext.servicesystemd-sysext statusif [[ -f "/usr/bin/python3" ]]; thenfatal "python3 binary found but sysext disabled"fiok "systemd system extensions functional"