mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-03 16:04:44 +01:00

This requires a runner with the tags: linux, x86_64, kvm. One needs to be provisioned for the AppArmor project for the pipeline to function. It is possible to run the same tests on SAAS runners offered by GitLab but due to issue gitlab-org/gitlab-runner#6208 there is no way to expose /dev/kvm on the host to the guest. Without this feature emulation works but is rather slow as to be impractical. Note that there's some overlap between the build-all job and spread that might be avoided in the future. At present this is made more difficult by the fact that the path where build-all job builds libapparmor is stored internally by autotools. This prevents us from using GitLab artifacts from moving the built files across to the spread testing jobs without extra work. In addition to adding the spread job, remove test-build-regression job. This job is now redundant since the same operation is done when spread builds and runs regression tests. Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com> MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1512 Approved-by: John Johansen <john@jjmx.net> Merged-by: John Johansen <john@jjmx.net>
287 lines
12 KiB
YAML
287 lines
12 KiB
YAML
project: apparmor
|
|
backends:
|
|
garden:
|
|
# The garden backend relies on https://gitlab.com/zygoon/image-garden
|
|
# TODO: Switch to a released version for better stability.
|
|
type: adhoc
|
|
allocate: |
|
|
# Use just enough RAM to link the parser on a virtual system with
|
|
# two cores. Using more cores may easily consume more memory, due
|
|
# to make -j$(nproc), used below than a small CI/CD system is
|
|
# typically granted. It is better to have more workers than to
|
|
# have one big worker with lots of resources.
|
|
export QEMU_MEM_OPTION="-m 1536"
|
|
export QEMU_SMP_OPTION="-smp 2"
|
|
ARCH="$(uname -m)"
|
|
# If a locally built kernel image exist then use it for booting.
|
|
# Care needs to be taken to make sure the kernel is compatible with
|
|
# loadable modules present in the file system.
|
|
if [ -f bzImage ]; then
|
|
# Create the qcow2/run files before setting custom kernel
|
|
# options, so that first boot and initialization happen in a
|
|
# standardized manner.
|
|
image-garden make "$SPREAD_SYSTEM"."$ARCH".run "$SPREAD_SYSTEM"."$ARCH".qcow2 1>&2
|
|
# Pass a simple drive instead of the more elaborate virtio
|
|
# configuration that is used by default. Some images may not
|
|
# support virtio enough for booting.
|
|
export QEMU_STORAGE_OPTION="-drive file=$SPREAD_SYSTEM.$ARCH.qcow2,format=qcow2"
|
|
# Refrain from passing EFI firmware to qemu so that we boot a
|
|
# kernel directly and bypass both EFI and BIOS.
|
|
export QEMU_BOOT_FIRMWARE_OPTION=""
|
|
# Pass the kernel and cmdline by hand. At present this is tuned
|
|
# to the Ubuntu cloud images that have the rootfs as the first
|
|
# partition.
|
|
exec image-garden allocate "$SPREAD_SYSTEM"."$ARCH" \
|
|
-kernel bzImage \
|
|
-append 'root=/dev/sda1 ro console=tty1 console=ttyS0'
|
|
fi
|
|
# Ask image garden to allocate the system and relay the result back
|
|
# to spread as either success of failure.
|
|
exec image-garden allocate "$SPREAD_SYSTEM"."$ARCH"
|
|
discard: image-garden discard "$SPREAD_SYSTEM_ADDRESS"
|
|
systems:
|
|
# All systems except for the one Ubuntu system are marked as
|
|
# manual. This way we don't accidentally spin up everything when
|
|
# someone runs spread without knowing better.
|
|
- opensuse-cloud-tumbleweed:
|
|
username: opensuse
|
|
password: opensuse
|
|
workers: 4
|
|
manual: true
|
|
- debian-cloud-12:
|
|
username: debian
|
|
password: debian
|
|
workers: 4
|
|
manual: true
|
|
- debian-cloud-13:
|
|
username: debian
|
|
password: debian
|
|
workers: 4
|
|
manual: true
|
|
- ubuntu-cloud-22.04:
|
|
username: ubuntu
|
|
password: ubuntu
|
|
workers: 4
|
|
manual: true
|
|
- ubuntu-cloud-24.04:
|
|
username: ubuntu
|
|
password: ubuntu
|
|
manual: true
|
|
- ubuntu-cloud-24.10:
|
|
username: ubuntu
|
|
password: ubuntu
|
|
workers: 4
|
|
- fedora-cloud-41:
|
|
username: fedora
|
|
password: fedora
|
|
|
|
exclude:
|
|
- .git
|
|
- "*.o"
|
|
# Files related to spread and image-garden.
|
|
- "*.qcow2"
|
|
- "*.iso"
|
|
- "*.img"
|
|
- "*.log"
|
|
- "*.run"
|
|
- "*.lock"
|
|
- spread-logs
|
|
- spread-artifacts
|
|
# Locally provided kernel image. See allocate section in system backends,
|
|
# this image, if present, is passed directly to qemu.
|
|
- bzImage
|
|
|
|
# Copy the project to this path on the test system.
|
|
# This is also available as $SPREAD_PATH.
|
|
path: /tmp/apparmor
|
|
|
|
prepare: |
|
|
# Configure libapparmor but only if a makefile is not already present.
|
|
# This makes repeated iteration with -reuse much faster, as the chain of
|
|
# invocations of make below are efficient if nothing needs to be done.
|
|
if [ ! -f "$SPREAD_PATH"/libraries/libapparmor/Makefile ]; then
|
|
(
|
|
cd "$SPREAD_PATH"/libraries/libapparmor || exit 1
|
|
if ! sh ./autogen.sh; then
|
|
echo "The autogen.sh script has failed"
|
|
exit 1
|
|
fi
|
|
if ! sh ./configure --prefix=/usr --with-perl --with-python; then
|
|
echo "The generated configure script has failed"
|
|
cat config.log
|
|
exit 1
|
|
fi
|
|
)
|
|
fi
|
|
# Build libapparmor.
|
|
make -C "$SPREAD_PATH"/libraries/libapparmor -j"$(nproc)"
|
|
# Build apparmor_parser.
|
|
make -C "$SPREAD_PATH"/parser -j"$(nproc)"
|
|
# Build binary utilities (aa-exec and firends).
|
|
make -C "$SPREAD_PATH"/binutils -j"$(nproc)"
|
|
# Build python utilities.
|
|
make -C "$SPREAD_PATH"/utils -j"$(nproc)"
|
|
# Build apache and pam modules.
|
|
make -C "$SPREAD_PATH"/changehat/mod_apparmor -j"$(nproc)"
|
|
make -C "$SPREAD_PATH"/changehat/pam_apparmor -j"$(nproc)"
|
|
|
|
# In case of failure, include the kernel version in the log.
|
|
debug-each: |
|
|
uname -a
|
|
|
|
suites:
|
|
tests/profiles/:
|
|
summary: Tests that exercise specific application profiles
|
|
systems:
|
|
# AppArmor is not enabled in the kernel.
|
|
- -fedora-cloud-*
|
|
# variables:
|
|
# PROFILE_NAME: name of the profile on disk
|
|
# PROGRAM_NAME: name of the program to execute
|
|
prepare-each: |
|
|
rm -f denials.txt
|
|
|
|
# Disable rate-limiting so that we see all denials.
|
|
sysctl --values kernel.printk_ratelimit >old-ratelimit.txt
|
|
sysctl --write kernel.printk_ratelimit=0
|
|
|
|
# Stop auditd so that all denials end up in the ring buffer.
|
|
if [ "$(systemctl is-active auditd.service)" != inactive ]; then
|
|
systemctl stop auditd.service
|
|
touch did-stop-auditd.txt
|
|
fi
|
|
|
|
# Clear the kernel ring buffer.
|
|
dmesg --clear
|
|
|
|
# Compute profile name from the name of the task.
|
|
echo "PROFILE_NAME=${PROFILE_NAME:=$(basename "$SPREAD_TASK")}"
|
|
|
|
"$SPREAD_PATH"/parser/apparmor_parser \
|
|
--warn=all \
|
|
--replace \
|
|
--skip-cache \
|
|
--base="$SPREAD_PATH"/profiles/apparmor.d \
|
|
"$SPREAD_PATH"/profiles/apparmor.d/"$PROFILE_NAME" 2>parser.txt
|
|
if [ -s parser.txt ]; then
|
|
echo "Parser produced warnings:"
|
|
cat parser.txt
|
|
exit 1
|
|
fi
|
|
|
|
restore-each: |
|
|
# Compute profile name from the name of the task.
|
|
echo "PROFILE_NAME=${PROFILE_NAME:=$(basename "$SPREAD_TASK")}"
|
|
|
|
"$SPREAD_PATH"/parser/apparmor_parser \
|
|
--base="$SPREAD_PATH"/profiles/apparmor.d \
|
|
--remove \
|
|
"$SPREAD_PATH"/profiles/apparmor.d/"$PROFILE_NAME"
|
|
|
|
# Restore auditd and old rate-limit.
|
|
if [ -f did-stop-auditd.txt ]; then
|
|
systemctl start auditd.service
|
|
rm -f did-stop-auditd.txt
|
|
fi
|
|
if [ -f old-ratelimit.txt ]; then
|
|
sysctl -w kernel.printk_ratelimit="$(cat old-ratelimit.txt)"
|
|
rm -f old-ratelimit.txt
|
|
fi
|
|
|
|
# Check if running the test resulted in any logged denials.
|
|
if dmesg | grep DENIED > denials.txt; then
|
|
if [ -z "${EXPECT_DENIALS:-}" ]; then
|
|
echo "Denials were emitted during the test."
|
|
cat denials.txt
|
|
exit 1
|
|
else
|
|
readarray -t regexes <<< $(printf "%b" "$EXPECT_DENIALS")
|
|
declare -a found_regex_array
|
|
|
|
# Check if all generated denials match the expected ones
|
|
while read denial; do
|
|
found=0
|
|
for i in "${!regexes[@]}"; do
|
|
if grep -E -q "${regexes[i]}" <<< "$denial"; then
|
|
found_regex_array[$i]=1
|
|
found=1
|
|
fi
|
|
done
|
|
|
|
if [ $found -eq 0 ]; then
|
|
echo "Unexpected denial: $denial"
|
|
exit 1
|
|
fi
|
|
done <denials.txt
|
|
|
|
# Check if all denials correspond to a regex
|
|
for i in "${!regexes[@]}"; do
|
|
if [ -z ${found_regex_array[$i]:-} ] ; then
|
|
echo "Exected denial ${regexes[i]} was not found"
|
|
exit 1
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
debug-each: |
|
|
echo "PROGRAM_NAME=${PROGRAM_NAME:=$(basename "$SPREAD_TASK")}"
|
|
command -v "$PROGRAM_NAME"
|
|
|
|
utils/:
|
|
summary: Unit tests for the Python utilities.
|
|
prepare: |
|
|
# Generate apparmor profiles that the tests rely on.
|
|
make -C "$SPREAD_PATH"/parser/tst gen_xtrans gen_dbus
|
|
# Spread does not support programmatically generated test variants.
|
|
# Ensure that the list baked into utils/test/task.yaml contains all
|
|
# the files matching utils/test/test-*.py
|
|
fail=0
|
|
for V in $SPREAD_PATH/utils/test/test-*.py; do
|
|
Vdash="$(basename "$V" | sed -e 's,^test-,,' -e 's,\.py$,,')"
|
|
Vunder="$(basename "$V" | sed -e 's,^test-,,' -e 's,\.py$,,' -e 's,-,_,g')"
|
|
if ! grep -xF ' TEST/'"$Vunder"': '"$Vdash" "$SPREAD_PATH"/utils/test/task.yaml; then
|
|
echo "utils/test/task.yaml: missing test variant: TEST/$Vunder: $Vdash" >&2
|
|
fail=1
|
|
fi
|
|
done
|
|
if [ "$fail" -ne 0 ]; then
|
|
echo "exiting due to missing variants listed above" >&2
|
|
exit 1
|
|
fi
|
|
tests/unit/:
|
|
summary: Unit tests that do not exercise the kernel layer.
|
|
tests/regression/:
|
|
summary: Regression tests for parser-kernel interaction.
|
|
systems:
|
|
# AppArmor is not enabled in the kernel.
|
|
- -fedora-cloud-*
|
|
prepare: |
|
|
# Spread does not support programmatically generated test variants.
|
|
# Ensure that the list baked into tests/regression/apparmor/task.yaml
|
|
# contains all the tests defined in tests/regression/apparmor/Makefile.
|
|
echo '$(foreach t,$(TESTS),$(info TEST/$t))' | \
|
|
make -n -f "$SPREAD_PATH"/tests/regression/apparmor/Makefile -f /dev/stdin | \
|
|
grep -F TEST/ | \
|
|
cut -d / -f 2 | \
|
|
tee apparmor-regression-tests.txt
|
|
fail=0
|
|
while read -r V; do
|
|
if ! grep -xF ' TEST/'"$V"': 1' "$SPREAD_PATH"/tests/regression/apparmor/task.yaml; then
|
|
echo "tests/regression/task.yaml: missing test variant: TEST/$V" >&2
|
|
fail=1
|
|
fi
|
|
done <apparmor-regression-tests.txt
|
|
if [ "$fail" -ne 0 ]; then
|
|
echo "exiting due to missing variants listed above" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Build all the apparmor regression test programs.
|
|
make -C "$SPREAD_PATH"/tests/regression/apparmor -j"$(nproc)"
|
|
restore: |
|
|
rm -f apparmor-regression-tests.txt
|
|
tests/snapd/:
|
|
summary: Tests exercising a subset of behavior of snapd
|
|
systems:
|
|
# AppArmor is not enabled in the kernel.
|
|
- -fedora-cloud-*
|