assembler/qemu: refactor fs creation & mounting

Introduce a generic mkfs_for_type() function that will dispatch
to the correct mkfs function depending on the type. Additionally
refactor the partition creation and mounting code to handle more
than one partition.
This commit is contained in:
Christian Kellner 2019-12-11 19:32:03 +01:00 committed by Tom Gundersen
parent 9b9c604ab7
commit 9863b5ad10

View file

@ -60,13 +60,12 @@ STAGE_OPTS = """
""" """
@contextlib.contextmanager @contextlib.contextmanager
def mount(source): def mount(source, dest):
with tempfile.TemporaryDirectory(prefix="osbuild-mnt") as dest: subprocess.run(["mount", source, dest], check=True)
subprocess.run(["mount", source, dest], check=True) try:
try: yield dest
yield dest finally:
finally: subprocess.run(["umount", "-R", dest], check=True)
subprocess.run(["umount", "-R", dest], check=True)
def mkfs_ext4(device, uuid): def mkfs_ext4(device, uuid):
@ -77,6 +76,16 @@ def mkfs_xfs(device, uuid):
subprocess.run(["mkfs.xfs", "-m", f"uuid={uuid}", device], encoding='utf-8', check=True) subprocess.run(["mkfs.xfs", "-m", f"uuid={uuid}", device], encoding='utf-8', check=True)
def mkfs_for_type(device, uuid, fs_type):
if fs_type == "ext4":
maker = mkfs_ext4
elif fs_type == "xfs":
maker = mkfs_xfs
else:
raise ValueError("Unknown filesystem type")
maker(device, uuid)
def create_partition_table(image, options): def create_partition_table(image, options):
"""Set up the partition table of the image""" """Set up the partition table of the image"""
ptuuid = options["ptuuid"] ptuuid = options["ptuuid"]
@ -143,8 +152,6 @@ def install_grub2(image, fs_module, partition_offset):
def main(tree, output_dir, options, loop_client): def main(tree, output_dir, options, loop_client):
fmt = options["format"] fmt = options["format"]
filename = options["filename"] filename = options["filename"]
ptuuid = options["ptuuid"]
root_fs_uuid = options["root_fs_uuid"]
size = options["size"] size = options["size"]
root_fs_type = options.get("root_fs_type", "ext4") root_fs_type = options.get("root_fs_type", "ext4")
@ -172,17 +179,27 @@ def main(tree, output_dir, options, loop_client):
# The partition table # The partition table
partitions = create_partition_table(image, options) partitions = create_partition_table(image, options)
partition_offset = partitions[0]["start"] partition_offset = partitions[0]["start"]
partition_size = partitions[0]["size"]
# Create the level-2 bootloader # Create the level-2 bootloader
install_grub2(image, grub2_fs_module, partition_offset) install_grub2(image, grub2_fs_module, partition_offset)
with loop_client.device(image, partition_offset, partition_size) as loop: # Now assemble the filesystem hierarchy and copy the tree into the image
# Populate the first partition of the image with a filesystem with contextlib.ExitStack() as cm:
mkfs(loop, root_fs_uuid) root = cm.enter_context(tempfile.TemporaryDirectory(prefix="osbuild-mnt"))
# Copy the tree into the target image # sort the partition according to their position in the filesystem tree
with mount(loop) as mountpoint: for partition in sorted(partitions, key=lambda p: len(p["filesystem"]["mountpoint"])):
subprocess.run(["cp", "-a", f"{tree}/.", mountpoint], check=True) offset, size = partition["start"], partition["size"]
filesystem = partition["filesystem"]
loop = cm.enter_context(loop_client.device(image, offset, size))
# make the specified filesystem
mkfs_for_type(loop, filesystem["uuid"], filesystem["type"])
# now mount it
mountpoint = os.path.normpath(f"{root}/{filesystem['mountpoint']}")
os.makedirs(mountpoint, exist_ok=True)
cm.enter_context(mount(loop, mountpoint))
# the filesystem tree should now be properly setup,
# copy the tree into the target image
subprocess.run(["cp", "-a", f"{tree}/.", root], check=True)
if fmt == "raw": if fmt == "raw":
subprocess.run(["cp", image, f"{output_dir}/{filename}"], check=True) subprocess.run(["cp", image, f"{output_dir}/{filename}"], check=True)