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:
parent
9b9c604ab7
commit
9863b5ad10
1 changed files with 33 additions and 16 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue