This is a crucial pre-condition for the org.osbuild.selinux stage to work properly, especially that it can set labels that are not present in the policy on the host. If /sys/fs/selinux is writable, setfiles will try to verify the labels via /sys/fs/selinux/context and fail for unknown labels.
110 lines
3.4 KiB
Python
110 lines
3.4 KiB
Python
#
|
|
# Test for the build root
|
|
#
|
|
|
|
import pathlib
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
|
|
import osbuild
|
|
from osbuild.buildroot import BuildRoot
|
|
from osbuild.monitor import NullMonitor
|
|
from .. import test
|
|
|
|
|
|
@unittest.skipUnless(test.TestBase.can_bind_mount(), "root-only")
|
|
class TestBuildRoot(test.TestBase):
|
|
"""Check BuildRoot"""
|
|
def setUp(self):
|
|
self.tmp = tempfile.TemporaryDirectory()
|
|
|
|
def tearDown(self):
|
|
self.tmp.cleanup()
|
|
|
|
def test_basic(self):
|
|
# This also checks the API and BuildRoot integration:
|
|
# the runner will call api.setup_stdio and thus check
|
|
# that connecting to the api works correctly
|
|
runner = "org.osbuild.linux"
|
|
libdir = os.path.abspath(os.curdir)
|
|
var = pathlib.Path(self.tmp.name, "var")
|
|
var.mkdir()
|
|
|
|
monitor = NullMonitor(sys.stderr.fileno())
|
|
with BuildRoot("/", runner, libdir=libdir, var=var) as root:
|
|
api = osbuild.api.API({}, monitor)
|
|
root.register_api(api)
|
|
|
|
r = root.run(["/usr/bin/true"])
|
|
self.assertEqual(r.returncode, 0)
|
|
|
|
# Test we can use `.run` multiple times
|
|
r = root.run(["/usr/bin/true"])
|
|
self.assertEqual(r.returncode, 0)
|
|
|
|
r = root.run(["/usr/bin/false"])
|
|
self.assertNotEqual(r.returncode, 0)
|
|
|
|
@unittest.skipUnless(test.TestBase.have_test_data(), "no test-data access")
|
|
def test_bind_mounts(self):
|
|
runner = "org.osbuild.linux"
|
|
libdir = os.path.abspath(os.curdir)
|
|
var = pathlib.Path(self.tmp.name, "var")
|
|
var.mkdir()
|
|
|
|
rw_data = pathlib.Path(self.tmp.name, "data")
|
|
rw_data.mkdir()
|
|
|
|
scripts = os.path.join(self.locate_test_data(), "scripts")
|
|
|
|
monitor = NullMonitor(sys.stderr.fileno())
|
|
with BuildRoot("/", runner, libdir=libdir, var=var) as root:
|
|
api = osbuild.api.API({}, monitor)
|
|
root.register_api(api)
|
|
|
|
ro_binds = [f"{scripts}:/scripts"]
|
|
|
|
cmd = ["/scripts/mount_flags.py",
|
|
"/scripts",
|
|
"ro"]
|
|
|
|
r = root.run(cmd, readonly_binds=ro_binds)
|
|
self.assertEqual(r.returncode, 0)
|
|
|
|
cmd = ["/scripts/mount_flags.py",
|
|
"/rw-data",
|
|
"ro"]
|
|
|
|
binds = [f"{rw_data}:/rw-data"]
|
|
r = root.run(cmd, binds=binds, readonly_binds=ro_binds)
|
|
self.assertEqual(r.returncode, 1)
|
|
|
|
@unittest.skipUnless(test.TestBase.have_test_data(), "no test-data access")
|
|
@unittest.skipUnless(os.path.exists("/sys/fs/selinux"), "no SELinux")
|
|
def test_selinuxfs_ro(self):
|
|
# /sys/fs/selinux must never be writable in the container
|
|
# because RPM and other tools must not assume the policy
|
|
# of the host is the valid policy
|
|
|
|
runner = "org.osbuild.linux"
|
|
libdir = os.path.abspath(os.curdir)
|
|
var = pathlib.Path(self.tmp.name, "var")
|
|
var.mkdir()
|
|
|
|
scripts = os.path.join(self.locate_test_data(), "scripts")
|
|
|
|
monitor = NullMonitor(sys.stderr.fileno())
|
|
with BuildRoot("/", runner, libdir=libdir, var=var) as root:
|
|
api = osbuild.api.API({}, monitor)
|
|
root.register_api(api)
|
|
|
|
ro_binds = [f"{scripts}:/scripts"]
|
|
|
|
cmd = ["/scripts/mount_flags.py",
|
|
"/sys/fs/selinux",
|
|
"ro"]
|
|
|
|
r = root.run(cmd, readonly_binds=ro_binds)
|
|
self.assertEqual(r.returncode, 0)
|