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.
This commit is contained in:
parent
2e4d610633
commit
5112f72cbf
6 changed files with 161 additions and 12 deletions
122
test/run/test_mount.py
Executable file
122
test/run/test_mount.py
Executable file
|
|
@ -0,0 +1,122 @@
|
|||
#!/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
|
||||
Loading…
Add table
Add a link
Reference in a new issue