Skip to content

Commit

Permalink
Add automated testing of SELinux relabelling functionality
Browse files Browse the repository at this point in the history
Initially copied from combustion, adjusted for microos-tools testing.
  • Loading branch information
Vogtinator committed Sep 26, 2024
1 parent a47b0cd commit dce1bac
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 2 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: MicroOS in QEMU
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
container:
image: opensuse/tumbleweed
options: --privileged
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
zypper in -y autoconf automake e2fsprogs gcc make dracut qemu-img qemu-x86 rpm-devel wget
- name: Build
run: |
./autogen.sh
./configure --sysconfdir=/etc
make -j$(nproc)
- name: Test
run: |
bash test/test.sh
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ and not shared one in /tmp.

## SELinux

MicroOS has preliminary support for SELinux.
MicroOS has support for SELinux.
If the file `/etc/selinux/.autorelabel` exists, the dracut module
`98selinux-microos` will label the root filesystem including
`/etc` and `/var`.
`/etc` and `/var`. The selinux-autorelabel-generator will generate
services to relabel other mountpoints during boot.

There is a script for automated testing of this in test/test.sh.

## locale-check

Expand Down
98 changes: 98 additions & 0 deletions test/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/bin/bash
set -euxo pipefail

# Some basic testing, mostly for the SELinux relabelling on first boot:
# 1. Download the latest MicroOS image
# 2. Use combustion to install microos-selinux, regenerate the initrd
# and transfer kernel + initrd to the host using 9pfs
# 3. Revert the image to the original state
# 4. Boot the image with the new initrd and use combustion to perform
# some tests to ensure the system booted correctly and was properly
# labelled.

# Skip the generation of a new initrd with the changed combustion.
# Only useful when iterating this test script.
reuseinitrd=
if [ "${1-}" = "--reuseinitrd" ]; then
reuseinitrd=1
shift
fi

# Working dir which is also exposed to the VM through 9pfs.
# If not specified, create a temporary directory which is deleted on exit.
if [ -n "${1-}" ]; then
tmpdir="$(realpath "$1")"
else
tmpdir="$(mktemp -d)"
cleanup() {
rm -rf "$tmpdir"
}
trap cleanup EXIT
fi

QEMU_BASEARGS=(
# -accel tcg was here after -accel kvm but the fallback hid a weird bug
# that in GH actions only the first instance of QEMU was able to access /dev/kvm.
-accel kvm -nographic -m 1024 -smp 4
# Reading from stdin doesn't work, configure serial and monitor appropriately.
-chardev null,id=serial,logfile=/dev/stdout,logappend=on -serial chardev:serial -monitor none
-virtfs "local,path=${tmpdir},mount_tag=tmpdir,security_model=mapped-xattr")

# Prepare the temporary dir: Install microos-tools and copy resources.
testdir="$(dirname "$0")"
make -C "${testdir}/.." install "DESTDIR=${tmpdir}/install"
cp "${testdir}/testscript" "${tmpdir}"
cd "$tmpdir"

# Download latest MicroOS image
if ! [ -f openSUSE-MicroOS.x86_64-kvm-and-xen.qcow2 ]; then
wget --progress=bar:force:noscroll https://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-kvm-and-xen.qcow2
qemu-img snapshot -c initial openSUSE-MicroOS.x86_64-kvm-and-xen.qcow2
else
qemu-img snapshot -a initial openSUSE-MicroOS.x86_64-kvm-and-xen.qcow2
fi

# First step: Use combustion in the downloaded image to generate an initrd with the new 98selinux-microos.
if ! [ -n "${reuseinitrd}" ] || ! [ -e "${tmpdir}/vmlinuz" ] || ! [ -e "${tmpdir}/initrd" ]; then
rm -f "${tmpdir}/done"
cat >create-initrd <<'EOF'
#!/bin/bash
# Workaround for https://bugzilla.opensuse.org/show_bug.cgi?id=1230912
# combustion: network
set -euxo pipefail
exec &>/dev/ttyS0
trap '[ $? -eq 0 ] || poweroff -f' EXIT
mount -t 9p -o trans=virtio tmpdir /mnt
cp -av /mnt/install/usr /
cp /usr/lib/modules/$(uname -r)/vmlinuz /mnt/vmlinuz
dracut -f --no-hostonly /mnt/initrd
touch /mnt/done
umount /mnt
SYSTEMD_IGNORE_CHROOT=1 poweroff -f
EOF

timeout 300 qemu-system-x86_64 "${QEMU_BASEARGS[@]}" -drive if=virtio,file=openSUSE-MicroOS.x86_64-kvm-and-xen.qcow2 \
-fw_cfg name=opt/org.opensuse.combustion/script,file=create-initrd

if ! [ -e "${tmpdir}/done" ]; then
echo "Initrd generation failed"
exit 1
fi
fi

# Test using a config drive
rm -f "${tmpdir}/done"
qemu-img snapshot -a initial openSUSE-MicroOS.x86_64-kvm-and-xen.qcow2

mkdir -p configdrv/combustion/
cp testscript configdrv/combustion/script
/sbin/mkfs.ext4 -F -d configdrv -L ignition combustion.raw 16M

timeout 300 qemu-system-x86_64 "${QEMU_BASEARGS[@]}" -drive if=virtio,file=openSUSE-MicroOS.x86_64-kvm-and-xen.qcow2 \
-kernel vmlinuz -initrd initrd -append "root=LABEL=ROOT console=ttyS0 security=selinux selinux=1 quiet systemd.show_status=1 systemd.log_target=console systemd.journald.forward_to_console=1 rd.emergency=poweroff rd.shell=0" \
-drive if=virtio,file=combustion.raw

if ! [ -e "${tmpdir}/done" ]; then
echo "Test failed"
exit 1
fi
42 changes: 42 additions & 0 deletions test/testscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash
# Work around for https://bugzilla.opensuse.org/show_bug.cgi?id=1230912
# combustion: network
set -euxo pipefail
exec &>/dev/ttyS0
# Poweroff immediately on any failure to avoid unnecessary waiting.
trap '[ $? -eq 0 ] || poweroff -f' EXIT

# Remove old microos-tools
rpm -e --nodeps --noscripts --nodb microos-tools
# Install microos-tools
mount -t 9p -o trans=virtio tmpdir /mnt
chown -R root:root /mnt/install/usr
cp -av /mnt/install/usr /
umount /mnt

# Make sure that the system comes up good, leave a marker in the shared FS
# and power off the VM.
cat >>/usr/bin/combustion-validate <<'EOF'
#!/bin/bash
set -euxo pipefail
exec &>/dev/ttyS0
trap '[ $? -eq 0 ] || poweroff -f' EXIT
# Print a list of files which have SELinux label mismatches
if restorecon -nvR -e /.snapshots -e /run / | grep -v wtmpdb | grep "Would relabel"; then
echo "Some labels aren't correct?"
exit 1
fi
mount -t 9p -o trans=virtio tmpdir /mnt
touch /mnt/done
umount /mnt
poweroff -f
EOF
chmod a+x /usr/bin/combustion-validate

cat >>/etc/systemd/system/combustion-validate.service <<'EOF'
[Service]
ExecStart=/usr/bin/combustion-validate
[Install]
RequiredBy=default.target
EOF
systemctl enable combustion-validate.service

0 comments on commit dce1bac

Please sign in to comment.