From 4513e824be850fb5561d53659ebd6294c6f32af7 Mon Sep 17 00:00:00 2001 From: Alexander Mikhalitsyn Date: Fri, 7 Jun 2024 13:12:54 +0200 Subject: [PATCH] github: add lxcfs live upgrade compatibility test Signed-off-by: Alexander Mikhalitsyn (cherry picked from commit e5a5c8c7a5953dbccce5aab3e860f9b13339869a) --- .github/workflows/tests.yml | 63 +++++++++++++++ tests/live-upgrade-test.sh.in | 143 ++++++++++++++++++++++++++++++++++ tests/meson.build | 12 +++ 3 files changed, 218 insertions(+) create mode 100755 tests/live-upgrade-test.sh.in diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 57bd574f..0f360e4c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -93,3 +93,66 @@ jobs: run: | echo 1 | sudo tee /sys/fs/cgroup/cpuset/cgroup.clone_children || true sudo -E PATH="${PATH}" LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" build/tests/main.sh + + live-upgrade-compatibility: + name: Live upgrade test + strategy: + fail-fast: false + matrix: + compiler: + - gcc + - clang + os: + - ubuntu-22.04 + runs-on: ${{ matrix.os }} + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Install dependencies + run: | + sudo add-apt-repository universe + sudo apt-get update -qq + sudo apt-get install -qq gcc clang + sudo apt-get install -qq libfuse3-dev uuid-runtime + sudo apt-get install -qq python3 python3-setuptools + sudo pip3 install meson==0.55.1 ninja + + - name: Compiler version + env: + CC: ${{ matrix.compiler }} + run: | + ${CC} --version + + - name: Build PR head version + env: + CC: ${{ matrix.compiler }} + run: | + meson setup -Ddocs=false -Dtests=true -Dinit-script=systemd -Dprefix=/usr -Db_sanitize=address,undefined build/ + meson compile -C build + + - name: Build upstream head version + env: + CC: ${{ matrix.compiler }} + run: | + git clone -b stable-6.0 https://github.com/lxc/lxcfs.git ../upstream-lxcfs + cd ../upstream-lxcfs + meson setup -Ddocs=false -Dtests=true -Dinit-script=systemd -Dprefix=/usr -Db_sanitize=address,undefined build/ + meson compile -C build + + - name: Test + env: + CC: ${{ matrix.compiler }} + WORKSPACE_PATH: ${{ github.workspace }} + run: | + UPSTREAM_LXCFS_TREE=$(realpath ${WORKSPACE_PATH}/../upstream-lxcfs) + NEW_LXCFS_TREE="${WORKSPACE_PATH}" + + echo "${NEW_LXCFS_TREE}" + echo "${UPSTREAM_LXCFS_TREE}" + + cd $UPSTREAM_LXCFS_TREE + [ -f build/tests/live-upgrade-test.sh ] || exit 0 + + echo 1 | sudo tee /sys/fs/cgroup/cpuset/cgroup.clone_children || true + sudo -E PATH="${PATH}" LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" build/tests/live-upgrade-test.sh "${NEW_LXCFS_TREE}" diff --git a/tests/live-upgrade-test.sh.in b/tests/live-upgrade-test.sh.in new file mode 100755 index 00000000..a4e4374e --- /dev/null +++ b/tests/live-upgrade-test.sh.in @@ -0,0 +1,143 @@ +#!/bin/sh +# SPDX-License-Identifier: LGPL-2.1+ + +set -eu +[ -n "${DEBUG:-}" ] && set -x + +[ $(id -u) -eq 0 ] + +NEW_LXCFS_TREE=$1 + +echo "LXCFS trees:" +pwd +echo "${NEW_LXCFS_TREE}" + +# Run lxcfs testsuite +export LXCFSDIR=$(mktemp -d) +pidfile=$(mktemp) +export LXCFSPID=-1 + +cmdline=$(realpath $0) +dirname=$(dirname ${cmdline}) + +FAILED=1 +UNSHARE=1 +cleanup() { + echo "=> Cleaning up" + set +e + if [ $LXCFSPID -ne -1 ]; then + kill -9 $LXCFSPID + fi + if [ ${LXCFSDIR} != "/var/lib/lxcfs" ]; then + umount -l ${LXCFSDIR} + rmdir ${LXCFSDIR} + fi + rm -f ${pidfile} + if [ ${FAILED} -eq 1 ]; then + echo "=> FAILED at $TESTCASE" + exit 1 + fi + echo "=> PASSED" + exit 0 +} + +TESTCASE="setup" +lxcfs="{{LXCFS_BUILD_ROOT}}/lxcfs" + +if [ -x ${lxcfs} ]; then + if [ -n "${LD_LIBRARY_PATH:-}" ]; then + export LD_LIBRARY_PATH="{{LXCFS_BUILD_ROOT}}:${LD_LIBRARY_PATH}" + else + export LD_LIBRARY_PATH="{{LXCFS_BUILD_ROOT}}" + fi + echo "=> Spawning ${lxcfs} ${LXCFSDIR}" + ${lxcfs} --enable-cgroup -p ${pidfile} ${LXCFSDIR} & + LXCFSPID=$! +else + UNSHARE=0 + LXCFSPID=$(cat "{{RUNTIME_PATH}}/lxcfs.pid") + echo "=> Re-using host lxcfs" + rmdir $LXCFSDIR + export LXCFSDIR=/var/lib/lxcfs +fi + +trap cleanup EXIT HUP INT TERM + +count=1 +while ! mountpoint -q $LXCFSDIR; do + sleep 1s + if [ $count -gt 5 ]; then + echo "lxcfs failed to start" + false + fi + count=$((count+1)) +done + +RUNTEST() { + echo "" + echo "=> Running ${TESTCASE}" + + if [ "${UNSHARE:-1}" != "0" ]; then + unshare -fmp --mount-proc $* + else + $* + fi +} + +RUNTESTS() { + TESTCASE="Stress readdir" + RUNTEST ${dirname}/test_readdir + TESTCASE="test_proc" + RUNTEST ${dirname}/test_proc + TESTCASE="test_cgroup" + RUNTEST ${dirname}/test_cgroup + TESTCASE="test_read_proc.sh" + RUNTEST ${dirname}/test_read_proc.sh + TESTCASE="cpusetrange" + RUNTEST ${dirname}/test-cpusetrange + TESTCASE="meminfo hierarchy" + RUNTEST ${dirname}/test_meminfo_hierarchy.sh + + TESTCASE="SIGUSR2 virtualization mode switching" + echo "==> Switching to non-virtualization mode" + kill -USR2 $LXCFSPID + RUNTEST ${dirname}/test_sigusr2.sh + echo "==> Switching to virtualization mode" + kill -USR2 $LXCFSPID +} + +echo "" +echo "=> Running tests BEFORE reload" +RUNTESTS + +TESTCASE="liblxcfs reloading (with upgrade)" + +rm -f /tmp/lxcfs-iwashere + +echo "==> Ensure that lxcfs is functional BEFORE reload" +cat ${LXCFSDIR}/proc/uptime + +libdir="{{LXCFS_BUILD_ROOT}}" + +[ ! -f /tmp/lxcfs-iwashere ] +rm -f ${libdir}/liblxcfs.so ${libdir}/liblxcfs.la +cp ${NEW_LXCFS_TREE}/build/liblxcfstest.so ${libdir}/liblxcfs.so + +echo "==> Reload liblxcfs" +kill -USR1 $LXCFSPID +sleep 1 + +echo "==> Ensure that lxcfs is functional AFTER reload" +cat ${LXCFSDIR}/proc/uptime +sleep 1 +[ -f /tmp/lxcfs-iwashere ] + +echo "" +echo "=> Running tests AFTER reload" +RUNTESTS + +# Check for any defunct processes - children we didn't reap +n=`ps -ef | grep lxcfs | grep defunct | wc -l` +[ $n = 0 ] + +FAILED=0 diff --git a/tests/meson.build b/tests/meson.build index ad8699c2..d82d7be7 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -12,6 +12,18 @@ test_programs += custom_target( '@OUTPUT@', ]) +test_programs += custom_target( + 'live-upgrade-test.sh', + build_by_default: want_tests != false, + input: 'live-upgrade-test.sh.in', + output: 'live-upgrade-test.sh', + command: [ + meson_render_jinja2, + config_h, + '@INPUT@', + '@OUTPUT@', + ]) + test_programs += custom_target( 'test_cgroup', build_by_default: want_tests != false,