diff options
Diffstat (limited to 'scripts/image-build/raw_image.py')
-rw-r--r-- | scripts/image-build/raw_image.py | 79 |
1 files changed, 60 insertions, 19 deletions
diff --git a/scripts/image-build/raw_image.py b/scripts/image-build/raw_image.py index d850eead..2edfecd6 100644 --- a/scripts/image-build/raw_image.py +++ b/scripts/image-build/raw_image.py @@ -63,22 +63,38 @@ class BuildContext: return self - def __exit__(self, exc_type, exc_value, exc_tb): + def __exit__(self, exc_type, exc_value, traceback): print(f"I: Tearing down the raw image build environment in {self.work_dir}") - cmd(f"""umount {self.squash_dir}/dev/""") - cmd(f"""umount {self.squash_dir}/proc/""") - cmd(f"""umount {self.squash_dir}/sys/""") - - cmd(f"umount {self.squash_dir}/boot/efi") - cmd(f"umount {self.squash_dir}/boot") - - cmd(f"""umount {self.squash_dir}""") - cmd(f"""umount {self.iso_dir}""") - cmd(f"""umount {self.raw_dir}""") - cmd(f"""umount {self.efi_dir}""") + for mount in [ + f"{self.squash_dir}/dev/", + f"{self.squash_dir}/proc/", + f"{self.squash_dir}/sys/", + f"{self.squash_dir}/boot/efi", + f"{self.squash_dir}/boot", + f"{self.squash_dir}", + f"{self.iso_dir}", + f"{self.raw_dir}", + f"{self.efi_dir}" + ]: + if os.path.ismount(mount): + try: + cmd(f"umount {mount}") + except Exception as e: + print(f"W: Failed to umount {mount}: {e}") + + # Remove kpartx mappings if self.loop_device: - cmd(f"""losetup -d {self.loop_device}""") + mapper_base = os.path.basename(self.loop_device) + try: + cmd(f"kpartx -d {self.loop_device}") + except Exception as e: + print(f"W: Failed to remove kpartx mappings for {mapper_base}: {e}") + + try: + cmd(f"losetup -d {self.loop_device}") + except Exception as e: + print(f"W: Failed to detach loop device {self.loop_device}: {e}") def create_disk(path, size): cmd(f"""qemu-img create -f raw "{path}" {size}G""") @@ -106,14 +122,23 @@ def setup_loop_device(con, raw_file): def mount_image(con): import vyos.system.disk - from subprocess import Popen, PIPE, STDOUT - from re import match + try: + root = con.disk_details.partition['root'] + efi = con.disk_details.partition['efi'] + except (AttributeError, KeyError): + raise RuntimeError("E: No valid root or EFI partition found in disk details") + + vyos.system.disk.filesystem_create(efi, 'efi') + vyos.system.disk.filesystem_create(root, 'ext4') - vyos.system.disk.filesystem_create(con.disk_details.partition['efi'], 'efi') - vyos.system.disk.filesystem_create(con.disk_details.partition['root'], 'ext4') + print(f"I: Mounting root: {root} to {con.raw_dir}") + cmd(f"mount -t ext4 {root} {con.raw_dir}") + cmd(f"mount -t vfat {efi} {con.efi_dir}") - cmd(f"mount -t ext4 {con.disk_details.partition['root']} {con.raw_dir}") - cmd(f"mount -t vfat {con.disk_details.partition['efi']} {con.efi_dir}") + if not os.path.ismount(con.efi_dir): + cmd(f"mount -t vfat {con.disk_details.partition['efi']} {con.efi_dir}") + else: + print(f"I: {con.disk_details.partition['efi']} already mounted on {con.efi_dir}") def install_image(con, version): from glob import glob @@ -205,6 +230,22 @@ def create_raw_image(build_config, iso_file, work_dir): create_disk(raw_file, build_config["disk_size"]) setup_loop_device(con, raw_file) disk_details = parttable_create(con.loop_device, (int(build_config["disk_size"]) - 1) * 1024 * 1024) + + # Map partitions using kpartx + cmd(f"kpartx -av {con.loop_device}") + cmd("udevadm settle") + + # Resolve mapper names (example: /dev/mapper/loop0p2) + from glob import glob + mapper_base = os.path.basename(con.loop_device).replace("/dev/", "") + mapped_parts = sorted(glob(f"/dev/mapper/{mapper_base}p*")) + + if len(mapped_parts) < 3: + raise RuntimeError("E: Expected at least 3 partitions created by kpartx") + + disk_details.partition['efi'] = mapped_parts[1] + disk_details.partition['root'] = mapped_parts[2] + con.disk_details = disk_details mount_image(con) install_image(con, version) |