debian-forge/test/run/test_mount.py
Thomas Lavocat 5112f72cbf mounts: use the options object for mountopts
This modification will allow a user to ask to mount the system as read
only for instance. Which would be super useful for image-info who is
progressively using more of OSbuild internals to mount partitions.
2022-11-30 14:21:10 +01:00

122 lines
3.5 KiB
Python
Executable file

#!/usr/bin/python3
#
# Runtime Tests for Device Host Services
#
import errno
import json
import os
import subprocess
import sys
import tempfile
from contextlib import contextmanager
import pytest
from osbuild import devices, host, meta, mounts
from ..test import TestBase
@pytest.fixture(name="tmpdir")
def tmpdir_fixture():
with tempfile.TemporaryDirectory(prefix="test-devices-") as tmp:
yield tmp
@contextmanager
def make_arguments(opts):
os.mkdir("/run/osbuild/api")
with open("/run/osbuild/api/arguments", "w", encoding="utf-8") as f:
json.dump(opts, f)
try:
yield
finally:
os.remove("/run/osbuild/api/arguments")
os.rmdir("/run/osbuild/api")
@contextmanager
def make_dev_tmpfs(tmpdir):
dev_path = os.path.join(tmpdir, "dev")
os.makedirs(dev_path)
subprocess.run(["mount", "-t", "tmpfs", "-o", "nosuid", "none", dev_path], check=True)
yield dev_path
subprocess.run(["umount", "--lazy", dev_path], check=True)
@pytest.mark.skipif(not TestBase.can_bind_mount(), reason="root only")
def test_mount_ro(tmpdir):
index = meta.Index(os.curdir)
# create a file to contain an image
tree = os.path.join(tmpdir, "tree")
os.makedirs(tree)
size = 1024 * 1024
file = os.path.join(tree, "image.img")
with open(file, "wb") as f:
f.truncate(size)
# Create an FS in the image
mkfsopts = {
"devices": {
"device": {
"path": file
}
},
"options": {
"label": "TEST",
"uuid": "FEEDFACE-CAFE-4004-FEED-C0DEC0FFEE11"
}
}
with make_arguments(mkfsopts):
subprocess.run(
[os.path.join(os.curdir, "stages", "org.osbuild.mkfs.ext4")],
check=True,
stdout=sys.stdout,
stderr=sys.stderr)
with tempfile.TemporaryDirectory() as mountpoint:
with host.ServiceManager() as mgr:
with make_dev_tmpfs(tmpdir) as devpath:
# Device manager to open the loopback device
devmgr = devices.DeviceManager(mgr, devpath, tree)
# get a Device for the loopback
dev = devices.Device(
"loop",
index.get_module_info(
"Device",
"org.osbuild.loopback"
),
None,
{
"filename": "image.img",
"start": 0,
"size": size // 512 # size is in sectors / blocks
}
)
# open the device and get its loopback path
lpath = os.path.join(
devpath,
devmgr.open(dev)["path"]
)
# mount the loopback
mounts.MountManager(
devmgr,
mountpoint
).mount(
mounts.Mount(
lpath,
index.get_module_info("Mount", "org.osbuild.ext4"),
dev,
"/",
{"readonly": True}
)
)
# try to write in it, and failure to do so is a success
with pytest.raises(OSError) as err:
with open(os.path.join(mountpoint, "test"), "w", encoding="utf-8") as f:
f.write("should not work")
assert err.value.errno == errno.EROFS # Check that FS is read only