mirror of
https://github.com/rosalinux/image-builder.git
synced 2025-02-23 18:32:51 +00:00
117 lines
4.2 KiB
Python
117 lines
4.2 KiB
Python
#!/usr/bin/env python
|
|
|
|
import os
|
|
import subprocess
|
|
|
|
|
|
def create_disk_image(tmp_dir, config, vendor, device):
|
|
|
|
boot_size = config.get("BOOT_SIZE", "").rstrip("MB")
|
|
root_size = config.get("ROOT_SIZE", "0").rstrip("MB")
|
|
|
|
if not root_size:
|
|
print("Error: ROOT_SIZE is not defined in the configuration.")
|
|
return
|
|
|
|
if not boot_size:
|
|
boot_size = "0"
|
|
|
|
disk_image_path = os.path.join(tmp_dir, vendor, device, "disk.img")
|
|
os.makedirs(os.path.dirname(disk_image_path), exist_ok=True)
|
|
cmd = [
|
|
"dd",
|
|
"if=/dev/zero",
|
|
f"of={disk_image_path}",
|
|
"bs=1M",
|
|
f"count={int(boot_size) + int(root_size)}"
|
|
]
|
|
|
|
print(f"Creating disk image: {disk_image_path} size {root_size} MB")
|
|
subprocess.run(cmd, check=True)
|
|
print(f"Disk image created at {disk_image_path}")
|
|
return disk_image_path
|
|
|
|
|
|
def cleanup_loop_devices():
|
|
result = subprocess.run(["losetup", "-l", "-O", "NAME"], capture_output=True, text=True)
|
|
active_loops = result.stdout.splitlines()[1:]
|
|
|
|
for loop_device in active_loops:
|
|
loop_device = loop_device.strip()
|
|
if loop_device:
|
|
print(f"Detaching {loop_device}")
|
|
subprocess.run(["losetup", "-d", loop_device], check=False)
|
|
|
|
|
|
def setup_loop_device(disk_image_path):
|
|
cleanup_loop_devices()
|
|
|
|
cmd = ["losetup", "-fP", "--show", disk_image_path]
|
|
result = subprocess.run(cmd, check=True, capture_output=True, text=True)
|
|
loop_device = result.stdout.strip()
|
|
print(f"Disk image mounted to loop device {loop_device}")
|
|
return loop_device
|
|
|
|
def create_partitions(loop_device, config):
|
|
root_size = config.get("ROOT_SIZE", "1024MB").rstrip("MB")
|
|
root_fstype = config.get("ROOT_FSTYPE", "ext4")
|
|
boot_size = config.get("BOOT_SIZE", "0").rstrip("MB") # Default to 0 if not specified
|
|
boot_fstype = config.get("BOOT_FSTYPE", "ext4") # Default to ext4 if not specified
|
|
|
|
print(f"Creating partitions on {loop_device} using sgdisk...")
|
|
|
|
try:
|
|
# Clear existing partitions
|
|
subprocess.run(["sgdisk", "--zap-all", loop_device], check=True)
|
|
|
|
if int(boot_size) > 0:
|
|
# Create boot partition
|
|
# 16M here s empty space for u-boot
|
|
subprocess.run(["sgdisk",
|
|
"--new=1:16M:+{}M".format(boot_size),
|
|
"--typecode=1:8300", loop_device], check=True)
|
|
|
|
# Create root partition
|
|
subprocess.run(["sgdisk",
|
|
"--new=2:0:0",
|
|
"--typecode=2:8300", loop_device], check=True)
|
|
|
|
# Format partitions
|
|
if boot_fstype == "vfat":
|
|
subprocess.run(["mkfs.vfat", "-F", "32", f"{loop_device}p1"], check=True)
|
|
else:
|
|
subprocess.run(["mkfs.ext4", f"{loop_device}p1"], check=True)
|
|
subprocess.run(["mkfs.ext4", f"{loop_device}p2"], check=True)
|
|
|
|
print(f" - Boot partition ({boot_size}MB) created and formatted as {boot_fstype}")
|
|
print(f" - Root partition created and formatted as {root_fstype}")
|
|
|
|
else:
|
|
# Create single root partition
|
|
subprocess.run(["sgdisk", "--new=1:0:0", "--typecode=1:8300", loop_device], check=True)
|
|
subprocess.run(["mkfs.ext4", f"{loop_device}p1"], check=True)
|
|
print(f" - Single root partition created and formatted as {root_fstype}")
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Error creating partitions with sgdisk: {e}")
|
|
return False
|
|
|
|
print("Partitioning and formatting complete.")
|
|
return True
|
|
|
|
def mount_partitions(config, loop_device, tmp_dir, vendor, device):
|
|
rootfs_dir = os.path.join(tmp_dir, vendor, device, "rootfs")
|
|
os.makedirs(rootfs_dir, exist_ok=True)
|
|
boot_partition = f"{loop_device}p1"
|
|
root_partition = f"{loop_device}p2" if "BOOT_SIZE" in config else f"{loop_device}p1"
|
|
|
|
print(f"Mounting root (/) partition at {rootfs_dir}")
|
|
subprocess.run(["mount", root_partition, rootfs_dir], check=True)
|
|
|
|
if "BOOT_SIZE" in config:
|
|
boot_dir = os.path.join(rootfs_dir, "boot")
|
|
os.makedirs(boot_dir, exist_ok=True)
|
|
print(f"Mounting /boot partition at {boot_dir}")
|
|
subprocess.run(["mount", boot_partition, boot_dir], check=True)
|
|
|
|
print("Mounting complete.")
|